我正在制作一个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()
问题是您正在更改组合框的类。由于默认绑定绑定到窗口小部件的原始类名称,因此这有效地删除了组合框的所有内置行为。