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

How to handle variables of multiple check buttons inside a menu in 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 的 return 值分配给 command 参数。因此,当您的代码被执行时,print_groceries 定义 复选按钮时执行了三次。由于所有复选按钮最初都未选中,因此您会看到 False 打印了三次。


解决方案:

command 参数接受一个函数,而不是 return 由函数编辑的值(除非 return 值本身就是一个函数)。

要创建一个简单的函数,您可以使用 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()