以编程方式创建复选框并使用 tkinter 获取它们的值
Create checkboxes programatically and the get their values with tkinter
我在此 SO question 中修改了答案,但主要结构保持不变。我想知道如何向该字典添加复选框,然后遍历复选框的值? tkinter 中的复选框需要一个我最终会检查的变量,所以我不确定如何使用此方法创建变量。
如何在我上面提到的问题的答案中的每一行末尾创建复选框?
我尝试了以下(最后两行):
self.widgets[rowid] = {
"rowid": ttk.Label(table, text=rowid, width=20, anchor=CENTER, relief=SUNKEN),
"reviewer": ttk.Label(table, text=reviewer, width=20, anchor=CENTER, relief=SUNKEN),
"task": ttk.Label(table, text=task, width=20, anchor=CENTER, relief=SUNKEN),
"num_seconds_correction": ttk.Entry(table),
"num_seconds": ttk.Label(table, text=num_seconds, width=20, anchor=CENTER, relief=SUNKEN),
"start_time": ttk.Label(table, text=start_time, width=20, anchor=CENTER, relief=SUNKEN),
"end_time": ttk.Label(table, text=start_time, width=20, anchor=CENTER, relief=SUNKEN),
"checkbox_var": IntVar(),
"checkbox": ttk.Checkbutton(table)
}
在小部件放置在网格中的部分,我尝试将变量分配给复选框,然后将其放置在网格中(最后两行):
#this just puts everything in the grid in the right place
self.widgets[rowid]["rowid"].grid(row=row, column=0, sticky="nsew")
self.widgets[rowid]["reviewer"].grid(row=row, column=1, sticky="nsew")
self.widgets[rowid]["task"].grid(row=row, column=2, sticky="nsew")
self.widgets[rowid]["num_seconds_correction"].grid(row=row, column=3, sticky="nsew")
self.widgets[rowid]["num_seconds"].grid(row=row, column=4, sticky="nsew")
self.widgets[rowid]["start_time"].grid(row=row, column=5, sticky="nsew")
self.widgets[rowid]["end_time"].grid(row=row, column=6, sticky="nsew")
self.widgets[rowid]["checkbox"].config(variable=(self.widgets[rowid]["checkbox_var"]))
self.widgets[rowid]["checkbox"].grid(row=row, column=7, sticky="nsew")
这使得复选框显示在正确的位置。然后,当我遍历这些值以查看选中了哪些框时,即使选中了其中一些框,returns 0 对于所有这些框:
for rowid in sorted(self.widgets.keys()):
check_widget = self.widgets[rowid]["checkbox"]
delete_value = check_widget.get()
print(delete_value)
本次迭代 returns 即使复选框被选中,也只有 0。我在这里似乎做错了什么?是否与将变量分配给复选框有关?
然后我尝试了一些不同的东西:
self.check = IntVar()
self.widgets[rowid] = {
"rowid": ttk.Label(table, text=rowid, width=20, anchor=CENTER, relief=SUNKEN),
"reviewer": ttk.Label(table, text=reviewer, width=20, anchor=CENTER, relief=SUNKEN),
"task": ttk.Label(table, text=task, width=20, anchor=CENTER, relief=SUNKEN),
"num_seconds_correction": ttk.Entry(table),
"num_seconds": ttk.Label(table, text=num_seconds, width=20, anchor=CENTER, relief=SUNKEN),
"start_time": ttk.Label(table, text=start_time, width=20, anchor=CENTER, relief=SUNKEN),
"end_time": ttk.Label(table, text=start_time, width=20, anchor=CENTER, relief=SUNKEN),
"checkbox": ttk.Checkbutton(table, variable=self.check)
}
然后遍历它:
for rowid in sorted(self.widgets.keys()):
print(self.check.get())
但它只打印 0,有什么想法吗?
编辑
这是 class:
的整个实际状态
class Example(ttk.Frame):
def __init__(self, parent):
ttk.Frame.__init__(self, parent)
b = ttk.Button(self, text="Done!", command=self.upload_cor) #submit button
b.pack()
b2 = ttk.Button(self, text="Close", command=self.destroy_cor) #close button
b2.pack(side="right")
table = ttk.Frame(self)
table.pack(side="top", fill="both", expand=True)
data = results #results is the nested list with the query results of rows for one day
self.widgets = {}
row = 0
total=0 #this will keep track of the total of hours for that day
#this iteration creates all the labels and positions them
for rowid, reviewer, task, num_seconds, start_time, end_time in (data):
row += 1
self.check = BooleanVar()
#this is a dictionary, this makes it easier keep track of the values inside
#text boxes when they're changed
self.widgets[rowid] = {
"rowid": ttk.Label(table, text=rowid, width=20, anchor=CENTER, relief=SUNKEN),
"reviewer": ttk.Label(table, text=reviewer, width=20, anchor=CENTER, relief=SUNKEN),
"task": ttk.Label(table, text=task, width=20, anchor=CENTER, relief=SUNKEN),
"num_seconds_correction": ttk.Entry(table),
"num_seconds": ttk.Label(table, text=num_seconds, width=20, anchor=CENTER, relief=SUNKEN),
"start_time": ttk.Label(table, text=start_time, width=20, anchor=CENTER, relief=SUNKEN),
"end_time": ttk.Label(table, text=start_time, width=20, anchor=CENTER, relief=SUNKEN),
"checkbox": ttk.Checkbutton(table, variable=self.check)
}
total = total + int(num_seconds)
#this just puts everything in the grid in the right place
self.widgets[rowid]["rowid"].grid(row=row, column=0, sticky="nsew")
self.widgets[rowid]["reviewer"].grid(row=row, column=1, sticky="nsew")
self.widgets[rowid]["task"].grid(row=row, column=2, sticky="nsew")
self.widgets[rowid]["num_seconds_correction"].grid(row=row, column=3, sticky="nsew")
self.widgets[rowid]["num_seconds"].grid(row=row, column=4, sticky="nsew")
self.widgets[rowid]["start_time"].grid(row=row, column=5, sticky="nsew")
self.widgets[rowid]["end_time"].grid(row=row, column=6, sticky="nsew")
#self.widgets[rowid]["checkbox"].config(variable=(self.widgets[rowid]["checkbox_var"]))
self.widgets[rowid]["checkbox"].grid(row=row, column=7, sticky="nsew")
ttk.Label(table, text='Total:',width=20, anchor=E, relief=SUNKEN).grid(row=row+1, column=3) #this 2 display the total hours
ttk.Label(table, text=total, width=20, anchor=CENTER, relief=SUNKEN).grid(row=row+1, column=4) #spent on the selected day
table.grid_columnconfigure(1, weight=1)
table.grid_columnconfigure(2, weight=1)
# invisible row after last row gets all extra space
table.grid_rowconfigure(row+1, weight=1)
globals().update(locals())
#########################
#uploads the new values if they
#were changed
def upload_cor(self):
globals().update(locals())
for rowid in sorted(self.widgets.keys()):
print(self.check)
#here is where I need something to see if the boxes are checked
我修改了示例中的代码,添加了您添加的位。这是完整代码:
import tkinter as tk
class Example(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
b = tk.Button(self, text="Done!", command=self.upload_cor)
b.pack()
table = tk.Frame(self)
table.pack(side="top", fill="both", expand=True)
data = (
(45417, "rodringof", "CSP L2 Review", 0.000394, "2014-12-19 10:08:12", "2014-12-19 10:08:12"),
(45418, "rodringof", "CSP L2 Review", 0.000394, "2014-12-19 10:08:12", "2014-12-19 10:08:12"),
(45419, "rodringof", "CSP L2 Review", 0.000394, "2014-12-19 10:08:12", "2014-12-19 10:08:12"),
(45420, "rodringof", "CSP L2 Review", 0.000394, "2014-12-19 10:08:12", "2014-12-19 10:08:12"),
(45421, "rodringof", "CSP L2 Review", 0.000394, "2014-12-19 10:08:12", "2014-12-19 10:08:12"),
(45422, "rodringof", "CSP L2 Review", 0.000394, "2014-12-19 10:08:12", "2014-12-19 10:08:12"),
(45423, "rodringof", "CSP L2 Review", 0.000394, "2014-12-19 10:08:12", "2014-12-19 10:08:12"),
)
self.widgets = {}
row = 0
for rowid, reviewer, task, num_seconds, start_time, end_time in (data):
row += 1
self.widgets[rowid] = {
"rowid": tk.Label(table, text=rowid),
"reviewer": tk.Label(table, text=reviewer),
"task": tk.Label(table, text=task),
"num_seconds_correction": tk.Entry(table),
"num_seconds": tk.Label(table, text=num_seconds),
"start_time": tk.Label(table, text=start_time),
"end_time": tk.Label(table, text=start_time),
"checkbox_var": tk.IntVar(),
"checkbox": tk.Checkbutton(table)
}
self.widgets[rowid]["rowid"].grid(row=row, column=0, sticky="nsew")
self.widgets[rowid]["reviewer"].grid(row=row, column=1, sticky="nsew")
self.widgets[rowid]["task"].grid(row=row, column=2, sticky="nsew")
self.widgets[rowid]["num_seconds_correction"].grid(row=row, column=3, sticky="nsew")
self.widgets[rowid]["num_seconds"].grid(row=row, column=4, sticky="nsew")
self.widgets[rowid]["start_time"].grid(row=row, column=5, sticky="nsew")
self.widgets[rowid]["end_time"].grid(row=row, column=6, sticky="nsew")
self.widgets[rowid]["checkbox"].config(variable=(self.widgets[rowid]["checkbox_var"]))
self.widgets[rowid]["checkbox"].grid(row=row, column=7, sticky="nsew")
table.grid_columnconfigure(1, weight=1)
table.grid_columnconfigure(2, weight=1)
# invisible row after last row gets all extra space
table.grid_rowconfigure(row+1, weight=1)
def upload_cor(self):
for rowid in sorted(self.widgets.keys()):
entry_widget = self.widgets[rowid]["num_seconds_correction"]
new_value = entry_widget.get()
print("%s: %s" % (rowid, new_value))
for rowid in sorted(self.widgets.keys()):
check_var = self.widgets[rowid]["checkbox_var"]
print(check_var.get())
if check_var.get():
print('Check button checked')
if __name__ == "__main__":
root = tk.Tk()
Example(root).pack(fill="both", expand=True)
root.mainloop()
具体看upload_cor
。如您所见,我想获取复选框变量而不是 check_widget = self.widgets[rowid]["checkbox"]
。我认为这是您的代码的问题。您得到的是小部件,而不是与小部件关联的变量。希望对你有帮助。
我在此 SO question 中修改了答案,但主要结构保持不变。我想知道如何向该字典添加复选框,然后遍历复选框的值? tkinter 中的复选框需要一个我最终会检查的变量,所以我不确定如何使用此方法创建变量。
如何在我上面提到的问题的答案中的每一行末尾创建复选框?
我尝试了以下(最后两行):
self.widgets[rowid] = {
"rowid": ttk.Label(table, text=rowid, width=20, anchor=CENTER, relief=SUNKEN),
"reviewer": ttk.Label(table, text=reviewer, width=20, anchor=CENTER, relief=SUNKEN),
"task": ttk.Label(table, text=task, width=20, anchor=CENTER, relief=SUNKEN),
"num_seconds_correction": ttk.Entry(table),
"num_seconds": ttk.Label(table, text=num_seconds, width=20, anchor=CENTER, relief=SUNKEN),
"start_time": ttk.Label(table, text=start_time, width=20, anchor=CENTER, relief=SUNKEN),
"end_time": ttk.Label(table, text=start_time, width=20, anchor=CENTER, relief=SUNKEN),
"checkbox_var": IntVar(),
"checkbox": ttk.Checkbutton(table)
}
在小部件放置在网格中的部分,我尝试将变量分配给复选框,然后将其放置在网格中(最后两行):
#this just puts everything in the grid in the right place
self.widgets[rowid]["rowid"].grid(row=row, column=0, sticky="nsew")
self.widgets[rowid]["reviewer"].grid(row=row, column=1, sticky="nsew")
self.widgets[rowid]["task"].grid(row=row, column=2, sticky="nsew")
self.widgets[rowid]["num_seconds_correction"].grid(row=row, column=3, sticky="nsew")
self.widgets[rowid]["num_seconds"].grid(row=row, column=4, sticky="nsew")
self.widgets[rowid]["start_time"].grid(row=row, column=5, sticky="nsew")
self.widgets[rowid]["end_time"].grid(row=row, column=6, sticky="nsew")
self.widgets[rowid]["checkbox"].config(variable=(self.widgets[rowid]["checkbox_var"]))
self.widgets[rowid]["checkbox"].grid(row=row, column=7, sticky="nsew")
这使得复选框显示在正确的位置。然后,当我遍历这些值以查看选中了哪些框时,即使选中了其中一些框,returns 0 对于所有这些框:
for rowid in sorted(self.widgets.keys()):
check_widget = self.widgets[rowid]["checkbox"]
delete_value = check_widget.get()
print(delete_value)
本次迭代 returns 即使复选框被选中,也只有 0。我在这里似乎做错了什么?是否与将变量分配给复选框有关?
然后我尝试了一些不同的东西:
self.check = IntVar()
self.widgets[rowid] = {
"rowid": ttk.Label(table, text=rowid, width=20, anchor=CENTER, relief=SUNKEN),
"reviewer": ttk.Label(table, text=reviewer, width=20, anchor=CENTER, relief=SUNKEN),
"task": ttk.Label(table, text=task, width=20, anchor=CENTER, relief=SUNKEN),
"num_seconds_correction": ttk.Entry(table),
"num_seconds": ttk.Label(table, text=num_seconds, width=20, anchor=CENTER, relief=SUNKEN),
"start_time": ttk.Label(table, text=start_time, width=20, anchor=CENTER, relief=SUNKEN),
"end_time": ttk.Label(table, text=start_time, width=20, anchor=CENTER, relief=SUNKEN),
"checkbox": ttk.Checkbutton(table, variable=self.check)
}
然后遍历它:
for rowid in sorted(self.widgets.keys()):
print(self.check.get())
但它只打印 0,有什么想法吗?
编辑 这是 class:
的整个实际状态class Example(ttk.Frame):
def __init__(self, parent):
ttk.Frame.__init__(self, parent)
b = ttk.Button(self, text="Done!", command=self.upload_cor) #submit button
b.pack()
b2 = ttk.Button(self, text="Close", command=self.destroy_cor) #close button
b2.pack(side="right")
table = ttk.Frame(self)
table.pack(side="top", fill="both", expand=True)
data = results #results is the nested list with the query results of rows for one day
self.widgets = {}
row = 0
total=0 #this will keep track of the total of hours for that day
#this iteration creates all the labels and positions them
for rowid, reviewer, task, num_seconds, start_time, end_time in (data):
row += 1
self.check = BooleanVar()
#this is a dictionary, this makes it easier keep track of the values inside
#text boxes when they're changed
self.widgets[rowid] = {
"rowid": ttk.Label(table, text=rowid, width=20, anchor=CENTER, relief=SUNKEN),
"reviewer": ttk.Label(table, text=reviewer, width=20, anchor=CENTER, relief=SUNKEN),
"task": ttk.Label(table, text=task, width=20, anchor=CENTER, relief=SUNKEN),
"num_seconds_correction": ttk.Entry(table),
"num_seconds": ttk.Label(table, text=num_seconds, width=20, anchor=CENTER, relief=SUNKEN),
"start_time": ttk.Label(table, text=start_time, width=20, anchor=CENTER, relief=SUNKEN),
"end_time": ttk.Label(table, text=start_time, width=20, anchor=CENTER, relief=SUNKEN),
"checkbox": ttk.Checkbutton(table, variable=self.check)
}
total = total + int(num_seconds)
#this just puts everything in the grid in the right place
self.widgets[rowid]["rowid"].grid(row=row, column=0, sticky="nsew")
self.widgets[rowid]["reviewer"].grid(row=row, column=1, sticky="nsew")
self.widgets[rowid]["task"].grid(row=row, column=2, sticky="nsew")
self.widgets[rowid]["num_seconds_correction"].grid(row=row, column=3, sticky="nsew")
self.widgets[rowid]["num_seconds"].grid(row=row, column=4, sticky="nsew")
self.widgets[rowid]["start_time"].grid(row=row, column=5, sticky="nsew")
self.widgets[rowid]["end_time"].grid(row=row, column=6, sticky="nsew")
#self.widgets[rowid]["checkbox"].config(variable=(self.widgets[rowid]["checkbox_var"]))
self.widgets[rowid]["checkbox"].grid(row=row, column=7, sticky="nsew")
ttk.Label(table, text='Total:',width=20, anchor=E, relief=SUNKEN).grid(row=row+1, column=3) #this 2 display the total hours
ttk.Label(table, text=total, width=20, anchor=CENTER, relief=SUNKEN).grid(row=row+1, column=4) #spent on the selected day
table.grid_columnconfigure(1, weight=1)
table.grid_columnconfigure(2, weight=1)
# invisible row after last row gets all extra space
table.grid_rowconfigure(row+1, weight=1)
globals().update(locals())
#########################
#uploads the new values if they
#were changed
def upload_cor(self):
globals().update(locals())
for rowid in sorted(self.widgets.keys()):
print(self.check)
#here is where I need something to see if the boxes are checked
我修改了示例中的代码,添加了您添加的位。这是完整代码:
import tkinter as tk
class Example(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
b = tk.Button(self, text="Done!", command=self.upload_cor)
b.pack()
table = tk.Frame(self)
table.pack(side="top", fill="both", expand=True)
data = (
(45417, "rodringof", "CSP L2 Review", 0.000394, "2014-12-19 10:08:12", "2014-12-19 10:08:12"),
(45418, "rodringof", "CSP L2 Review", 0.000394, "2014-12-19 10:08:12", "2014-12-19 10:08:12"),
(45419, "rodringof", "CSP L2 Review", 0.000394, "2014-12-19 10:08:12", "2014-12-19 10:08:12"),
(45420, "rodringof", "CSP L2 Review", 0.000394, "2014-12-19 10:08:12", "2014-12-19 10:08:12"),
(45421, "rodringof", "CSP L2 Review", 0.000394, "2014-12-19 10:08:12", "2014-12-19 10:08:12"),
(45422, "rodringof", "CSP L2 Review", 0.000394, "2014-12-19 10:08:12", "2014-12-19 10:08:12"),
(45423, "rodringof", "CSP L2 Review", 0.000394, "2014-12-19 10:08:12", "2014-12-19 10:08:12"),
)
self.widgets = {}
row = 0
for rowid, reviewer, task, num_seconds, start_time, end_time in (data):
row += 1
self.widgets[rowid] = {
"rowid": tk.Label(table, text=rowid),
"reviewer": tk.Label(table, text=reviewer),
"task": tk.Label(table, text=task),
"num_seconds_correction": tk.Entry(table),
"num_seconds": tk.Label(table, text=num_seconds),
"start_time": tk.Label(table, text=start_time),
"end_time": tk.Label(table, text=start_time),
"checkbox_var": tk.IntVar(),
"checkbox": tk.Checkbutton(table)
}
self.widgets[rowid]["rowid"].grid(row=row, column=0, sticky="nsew")
self.widgets[rowid]["reviewer"].grid(row=row, column=1, sticky="nsew")
self.widgets[rowid]["task"].grid(row=row, column=2, sticky="nsew")
self.widgets[rowid]["num_seconds_correction"].grid(row=row, column=3, sticky="nsew")
self.widgets[rowid]["num_seconds"].grid(row=row, column=4, sticky="nsew")
self.widgets[rowid]["start_time"].grid(row=row, column=5, sticky="nsew")
self.widgets[rowid]["end_time"].grid(row=row, column=6, sticky="nsew")
self.widgets[rowid]["checkbox"].config(variable=(self.widgets[rowid]["checkbox_var"]))
self.widgets[rowid]["checkbox"].grid(row=row, column=7, sticky="nsew")
table.grid_columnconfigure(1, weight=1)
table.grid_columnconfigure(2, weight=1)
# invisible row after last row gets all extra space
table.grid_rowconfigure(row+1, weight=1)
def upload_cor(self):
for rowid in sorted(self.widgets.keys()):
entry_widget = self.widgets[rowid]["num_seconds_correction"]
new_value = entry_widget.get()
print("%s: %s" % (rowid, new_value))
for rowid in sorted(self.widgets.keys()):
check_var = self.widgets[rowid]["checkbox_var"]
print(check_var.get())
if check_var.get():
print('Check button checked')
if __name__ == "__main__":
root = tk.Tk()
Example(root).pack(fill="both", expand=True)
root.mainloop()
具体看upload_cor
。如您所见,我想获取复选框变量而不是 check_widget = self.widgets[rowid]["checkbox"]
。我认为这是您的代码的问题。您得到的是小部件,而不是与小部件关联的变量。希望对你有帮助。