在 Tkinter 组合框小部件中使用列表

问题描述 投票:0回答:3

我想使用组合框小部件来显示通过查询访问数据库填充的车辆列表。 相关代码如下

from O365 import *
import tkinter as tk 
from tkinter import ttk
from tkcalendar import *
import pyodbc 

root = tk.Tk()
root.title('Loan Car Manager')
root.geometry('800x1200')
style = ttk.Style(root)

load_loan_vehicle_list_button = tk.Button(root, command = get_active_loan_cars, text = "Load / Refresh")
load_loan_vehicle_list_button.place(x=50 , y=50)

conn = pyodbc.connect(r'DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};UID=admin;UserCommitSync=Yes;Threads=3;SafeTransactions=0;PageTimeout=5;MaxScanRows=8;MaxBufferSize=2048;{FIL=MS Access};DriverId=25;DefaultDir=C:\Users\James\Documents;DBQ=C:\Users\James\Documents\Database1.accdb;')
cursor = conn.cursor()



def get_active_loan_cars():
    global loan_list
    cursor.execute("SELECT Loan_make , Loan_model , Loan_rego  FROM Loan_vehicle_data WHERE is_active =  True")
    for row in cursor.fetchall():
        loan_list = []
        loan_list.append(row)
        loan_car_drop_down = ttk.Combobox(root)
        loan_car_drop_down.place(x=50 , y=70)
        loan_car_drop_down['values'] = loan_list
        print(loan_list)



root.mainloop()

当我运行此命令时,它会按预期查询数据库并将车辆返回到列表中

loan_list
..当我使用
combobox
将列表插入到
loan_car_drop_down['values'] = loan_list
时,它会显示列表,但记录显示在1行上.. 例如:

当我

print(loan_list)
它返回时:

[('现代', '伊兰特', 'TEST123')] [('现代', 'I30', 'ABC123')]

我的问题是如何让这些记录显示在

combobox
小部件的单独行上。 这是一张参考我的目标的图片。忽略此示例中显示的月份,我想将其替换为:

现代'、'伊兰特'、'TEST123' ‘现代’、‘I30’、‘ABC123’

python tkinter pyodbc
3个回答
1
投票

要在组合框中加载记录,我使用字典。

我将组合的索引与记录的主键耦合以加载到字典中。

下面有一个完整的例子,评论过。

该示例加载一个记录集,当您选择一个项目时,我添加了一些项目和一个整数主键 从组合中,它表示从字典中检索到的 pk 值。

在打开时,它也位于您使用 pk 选择的记录上。

希望您会发现它有用

#!/usr/bin/python3
import tkinter as tk
from tkinter import ttk
from tkinter import messagebox


class Main(ttk.Frame):
    def __init__(self, parent):
        super().__init__()

        self.parent = parent
        
        self.init_ui()
          
    def init_ui(self):

       
        self.pack(fill=tk.BOTH, expand=1)

        f = ttk.Frame(padding = 8)

        ttk.Label(f, text = "Combobox").pack()
        self.cbCombo = ttk.Combobox(f,)
        self.cbCombo.bind("<<ComboboxSelected>>", self.on_selected)
        self.cbCombo.pack()
        
        f.pack(fill=tk.BOTH, expand=1)

    def on_open(self,):

        self.set_combos()
        self.on_set_combo()
        
    def set_combos(self):

        index = 0
        self.dict_cars = {}
        voices = []

        #here your recordset, I've add some items and even a supposed primary key.....1,2,3,4,5
        rs = [(1, 'Hyundai', 'Elantra', 'TEST123'),
              (2, 'Hyundai', 'I30', 'ABC123'),
              (3, 'Hyundai', 'Azera', 'ABC123'),
              (4, 'Hyundai', 'Sonata', 'ABC123'),
              (5, 'Hyundai', 'I30 Fastback N', 'ABC123')]

        #here we coupling self.dict_cars with the combo index...
        for i in rs:
            self.dict_cars[index] = i[0]
            index += 1
            record = "{0} {1}".format(i[1], i[2])
            voices.append(record)

        self.cbCombo["values"] = voices        
        

    def on_selected(self, evt=None):
        #when you select an item on the combo it get the relative pk record from the dict
        index = self.cbCombo.current()
        pk = self.dict_cars[index]
        msg =  ("You have selected index {0} pk {1}".format(index, pk))

        messagebox.showinfo(self.master.title(),msg, parent=self)
        
    def on_set_combo(self):
        #it'use to select, on open a specific record, in that case the 5
        try:
            key = next(key
                       for key, value
                       in self.dict_cars.items()
                       if value == 5)
            self.cbCombo.current(key)
        except:
            pass
        
        
    def on_close(self):
        self.parent.on_exit()

class App(tk.Tk):
    """Start here"""

    def __init__(self):
        super().__init__()

        self.protocol("WM_DELETE_WINDOW", self.on_exit)
            
        self.set_title()
        self.set_style()
       
        frame = Main(self,)
        frame.on_open()
        frame.pack(fill=tk.BOTH, expand=1)

    def set_style(self):
        self.style = ttk.Style()
        #('winnative', 'clam', 'alt', 'default', 'classic', 'vista', 'xpnative')
        self.style.theme_use("clam")
        

    def set_title(self):
        s = "{0}".format('Simple App')
        self.title(s)
        
    def on_exit(self):
        """Close all"""
        if messagebox.askokcancel("Simple App", "Do you want to quit?", parent=self):
            self.destroy()               
    
if __name__ == '__main__':
    app = App()
    app.mainloop()


1
投票

使用

extend
代替
append

def get_active_loan_cars():
    loan_list = []
    cursor.execute("SELECT Loan_make , Loan_model , Loan_rego  FROM Loan_vehicle_data WHERE is_active =  True")
    for row in cursor.fetchall():
        loan_list.extend(row)

    loan_car_drop_down = ttk.Combobox(root)
    loan_car_drop_down.place(x=50 , y=70)
    loan_car_drop_down['values'] = loan_list
    print(loan_list)

0
投票

添加这个

combo ['value'] = all_users

© www.soinside.com 2019 - 2024. All rights reserved.