我在TKinter中有一个滚动框。以及我要使用for循环从列表(由SQlite管理)从数据库中获取的每个元组的列表,其中我想在滚动框中创建一行小部件。该行包括行号,一个复选框,取自元组的标题和一个打开取自元组的链接的按钮。我遇到的问题是,我不知道如何在TKinter中创建未知数量的小部件行,也无法引用它们。以下代码的工作方式是创建行等,但是一旦创建行,我将无法引用单个窗口小部件。这很重要,因为单击复选框需要更新数据库中的IsActive列(也欢迎提供帮助)。我曾尝试使用字典来保存StringVar()的复选框,但我确定我做错了。
类本身是TKinter窗口中的框架。我很高兴这是一个初学者,这可能是一个愚蠢的问题
class details(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = tk.Label(self, text="details", font=controller.title_font)
label.pack(side="top", fill="x", pady=10)
button = tk.Button(self, text="Go to the start page",
command=lambda: controller.show_frame("StartPage"))
button.place(relx=0.5, rely=0.95, anchor = tk.CENTER)
myframe= tk.Frame(self,relief=tk.GROOVE,bd=1)
myframe.place(relx=0.5, rely=0.45, anchor = tk.CENTER, width = 750, height = 450)
self.canvas=tk.Canvas(myframe)
self.frame=tk.Frame(self.canvas)
myscrollbar=tk.Scrollbar(myframe,orient="vertical",command=self.canvas.yview)
self.canvas.configure(yscrollcommand=myscrollbar.set)
myscrollbar.pack(side="right",fill="y")
self.canvas.pack(side="left", fill="both")
self.canvas.create_window((0,0),window=self.frame,anchor='nw')
self.frame.bind("<Configure>",self.myfunction)
self.data()
def data(self):
lock.acquire(True)
c.execute("select * from story")
lock.release()
results = c.fetchall()
print(results)
i = 0
checkbuttons = {}
## the for loop where rows are created.
for item in results:
checkbuttons[item[0]] = tk.IntVar()
b = item[4]
s = tk.StringVar()
tk.Label(self.frame,text=i).grid(row=i,column=0)
tk.Checkbutton(self.frame, text="", variable=checkbuttons[item[0]], onvalue=1, offvalue=0).grid(row=i,column=1)
tk.Label(self.frame,textvariable=s, width = 90).grid(row=i,column=2, sticky=tk.W)
tk.Button(self.frame,text="LINK", command=lambda a = b: self.open_link(a)).grid(row=i,column=3)
s.set(str(item[3]))
i+=1
def myfunction(self, event):
self.canvas.configure(scrollregion=self.canvas.bbox("all"),width=750,height=500)
def open_link(self, link):
print(link)
webbrowser.open(link, new=1)
答案 0 :(得分:0)
我遇到的问题是,我不知道如何在TKinter中创建未知数量的小部件行,也无法引用它们。
最简单的解决方案是将它们放在列表或字典中,或者在您的情况下,放在字典列表中,其中列表中的每一行都是包含您要记住的数据的字典。
因此,从要记住的数据开始。在您的情况下,我猜测我们希望能够获取href,并且希望能够获取或设置关联的变量。
在以下示例中,我尝试使用比b
,i
等更明智的变量名,并通过逻辑功能组织代码:从项目中提取数据,创建小部件,布置小部件,然后保存数据。
for rownum, item in enumerate(results):
title = item[3]
href = item[4]
var = tk.IntVar(value=0)
row_label = tk.Label(self.frame, text=rownum)
title_label = tk.Label(self.frame, text=title)
cb = tk.Checkbutton(self.frame, text="", variable=var,
onvalue=1, offvalue=0)
button = tk.Button(self.frame, text="LINK",
command=lambda rownum=rownum: self.open_link(rownum))
row_label.grid(row=rownum, column=0)
cb.grid(row=rownum, column=1)
title_label.grid(row=rownum, column=2, sticky="w")
button.grid(row=rownum, column=3)
# store the data in a dictionary so we can reference it later
row = {
"href": href,
"var": var
}
self.rows.append(row)
出于说明目的,我修改了open_link
以接受行号而不是链接。我们可以使用行号来访问href,我也让它自动选择关联的复选按钮以证明您可以。
def open_link(self, rownum):
link = self.rows[rownum]['href']
self.rows[rownum]['var'].set(1)
print(link)