如何在Tkinter中处理菜单中多个复选按钮的变量



我想在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()

最新更新