ttk.Combobox-单击时不显示下拉框

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

我正在制作一个Tkinter应用程序,该应用程序应该创建一系列组合框,并使用Sqlite数据库中的元素填充它们。但是,即使在为每个组合框填充values属性之后,也无法在应用程序实际启动后显示下拉菜单或与框进行交互。

我可以在开始主循环之前设置Combobox.current()索引,从而在该索引处显示值,但是一旦主循环开始,就根本无法与该框进行交互。我确实尝试使用后命令回调来填充列表,但是得到了相同的结果。在此过程中我没有任何错误。

注意:以下代码中已编码示例数据以替换数据库查询。这不会改变我的结果。

from tkinter import *
import tkinter.ttk as ttk

class PCFrame(Frame):

    def __init__(self, master):
        self.master = master
        super().__init__(master=master)
        self.columnconfigure(0, minsize=100, weight=1)
        self.columnconfigure(1, minsize=300, weight=3)
        self.grid()

        self.widgets = {}
        self.pc_fieldnames = ["computer name",
                              "customer name",
                              "serial",
                              "model"]
        self.init_ui()

    def init_ui(self):

        label_opts = {"column": 0, "sticky": W}
        field_opts = {"column": 1, "sticky": E + W}

        for rownum, i in enumerate(self.pc_fieldnames):
            #Callback for postcommand that didn't change my results
            def field_display_handler(self=self, fieldname=i):
                return self.field_display(fieldname)

            self.widgets[i] = {}

            self.widgets[i]["NewValue"] = StringVar(self,
                                                    value=None)
            #Values here are in the form (row_value, row_serial_num)
            #Combobox will always display the first item in 
            #each of the tuples
            self.widgets[i]["ValueTuples"] = []
            self.widgets[i]["Field"] = ttk.Combobox(self, class_="PCField",
                                    textvariable=self.widgets[i]["NewValue"],
                                    state = "normal",
                                    postcommand = field_display_handler,
                                    values = [])
            self.widgets[i]["Field"].rowname = i
            self.widgets[i]["Field"].grid(row=rownum, **field_opts)
            self.widgets[i]["Label"] = ttk.Label(self, text=i.capitalize())
            self.widgets[i]["Label"].rowname = i
            self.widgets[i]["Label"].grid(row=rownum, **label_opts)

        self.populate()
        for i in self.pc_fieldnames:
            self.field_display(i)
            self.widgets[i]["Field"].current(newindex=0)

    def populate(self, search_column = None, search_criteria = None, 
                rows=None):
        if rows == None:
            #Test values here, normally would use a DB query here
            rows = []
            for i in range(5):
                rows.append({})
                for j in self.pc_fieldnames:
                    rows[i][j] = j + " " + str(i)
        #Reinitialize, then populate, all fields
        for k, w in self.widgets.items():
            w["ValueTuples"] = []
        for row in rows:
            for key in row.keys():
                k = key.lower()
                entry = row[k] if row[k] != None else ""
                try:
                    self.widgets[k]["ValueTuples"].append(
                                                    (entry, row["serial"]))
                except KeyError:
                    if k not in self.pc_fieldnames:
                        pass
                    else:
                        raise

    def field_display(self, fieldname):
        display = []
        for i in self.widgets[fieldname]["ValueTuples"]:
            display.append(i[0])
        self.widgets[fieldname]["Field"]["values"] = display

if __name__ == "__main__":
    root = Tk()
    frame = PCFrame(root)
    root.mainloop()
python python-3.x tkinter combobox ttk
1个回答
0
投票

问题是您正在更改组合框的类。由于默认绑定绑定到窗口小部件的原始类名称,因此这有效地删除了组合框的所有内置行为。

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