python - Tkinter OptionMenu 向多个 OptionMenus 添加命令

标签 python lambda tkinter closures optionmenu

基本上我有一系列在循环中创建的 OptionMenus,但目前是空的:

option_menu = []
for ii in range(jj):
    option_menu.append([])  
    for ll in range(kk):   
        option_menu[ii].append(OptionMenu(frame,tkinter_text_var[ii][ll],''))

然后在其他地方我使用复选框来设置值:

for ii in range(jj):
    for ll in range(kk):   
        option_menu[ii][ll]["menu"].add_command(label = name_from_box.get(), command = lambda: tkinter_text_var[ii][ll].set(name_from_box.get()))

这可以正确填充所有 OptionMenus,但是当我在任何 OptionMenus 中选择一个值时,它只会设置 option_menu[jj][kk](即最后一个)。

那我做错了什么?

最佳答案

这是一个非常涉及闭包的常见问题。看下面的例子:

alist = [lambda : x for x in range(10) ]
print (alist[2]()) #9
print (alist[4]()) #9

全部都是 9。为什么?因为每个 lambda 函数都引用变量 xx 在循环的每次迭代中都会发生变化,但它们仍然指代同一个对象

解决此问题的一种方法是使用默认参数。默认参数在创建函数时计算,而不是在调用时计算。

alist = [lambda y=x: y for x in range(10) ]
print (alist[2]()) #2
print (alist[4]()) #4

(做同样事情的另一种方法涉及 functools.partial,您有时会看到...)

我经常喜欢说——“小心闭包”。它们可能有点棘手。

关于python - Tkinter OptionMenu 向多个 OptionMenus 添加命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11801121/

相关文章:

python - 不使用小部件 tk.Menu 的自定义菜单栏

python - 从 Python 调用 AWS Rekognition HTTP API 的示例

python 多个列表中的最小范围

lambda - Sonar : lambda - Remove useless curly braces around statement

超出 Python tkinter Canvas root.after() 最大递归深度

python - Tkinter 文本小部件间距

python - 在两个字符串中查找所有公共(public)子字符串的函数没有给出正确的输出

python - 关于MySQL "SELECT *"的内存问题

c# - 什么时候太多 "lambda action"?

c++ - 为什么 init-capturing 可变 lambda 不能有可变数据成员?