我想在Tkinter中制作一个多选下拉列表,所以在线浏览时,我找到了在菜单中使用add_checkbuttons
的解决方案。它正在运行的解决方案,至少在图形上是这样,但现在我希望GUI在标记检查时实际执行一些操作。我尝试了一个简单的函数,将值打印为每个复选按钮的命令,但它只被调用一次。
到目前为止,这是我的代码:
root = tk.Tk()
groceries = ['Apple', 'Banana', 'Carrot']
def print_groceries(bucket,item):
print(bucket[item].get())
menubar = tk.Menu(root)
viewMenu = tk.Menu(menubar, tearoff = 0)
bucket={}
for item in groceries:
bucket[item] = tk.BooleanVar(False)
viewMenu.add_checkbutton(label = item, variable = bucket[item], command=print_groceries(bucket,item))
menubar.add_cascade(menu = viewMenu, label = "Buy")
root.config(menu = menubar)
root.mainloop()
您已将print_groceries
的返回值分配给command
参数。因此,当执行代码时,print_groceries
会在定义复选按钮时执行三次。由于最初未选中所有的复选按钮,您可以看到False
被打印了三次。
解决方案:
command
参数采用函数,而不是函数返回的值(除非返回值本身是函数(。
要创建一个简单的函数,可以使用lambda
,如下所示:
lambda <parameter-1>,<parameter-2>,... : <task-to-perform>
此外,必须使用lambda bucket=bucket, item=item: print_groceries(bucket,item)
,而不是lambda : print_groceries(bucket,item)
。你可以在这个答案中找到同样的原因。
工作代码:
import tkinter as tk
root = tk.Tk()
groceries = ['Apple', 'Banana', 'Carrot']
def print_groceries(bucket,item):
print(bucket[item].get())
menubar = tk.Menu(root)
viewMenu = tk.Menu(menubar, tearoff = 0)
bucket={}
for item in groceries:
bucket[item] = tk.BooleanVar(False)
func = lambda bucket=bucket, item=item: print_groceries(bucket,item)
viewMenu.add_checkbutton(label = item, variable = bucket[item], command = func)
menubar.add_cascade(menu = viewMenu, label = "Buy")
root.config(menu = menubar)
root.mainloop()