Tkinter 在循环中使用 lambda 分配按钮命令

Posted

技术标签:

【中文标题】Tkinter 在循环中使用 lambda 分配按钮命令【英文标题】:Tkinter assign button command in a for loop with lambda [duplicate] 【发布时间】:2013-07-14 16:46:58 【问题描述】:

我正在尝试创建一些Buttons(带有for 循环),如下所示:

def a(self, name):
    print(name)

users = "Test": "127.0.0.0", "Test2": "128.0.0.0"
row = 1
for name in users:
    user_button = Tkinter.Button(self.root, text=name,
                                 command=lambda: self.a(name))
    user_button.grid(row=row, column=0)
    row += 1

每个按钮都有自己的参数(测试得到"Test"和Test2得到"Test2"),但是当我按下按钮时,它们都打印"Test2",这意味着它们使用相同的功能参数。

我该如何解决这个问题?

【问题讨论】:

【参考方案1】:

问题是你在 for 循环中的 Lamba。您的 lambda 正在使用 name 变量,但每次通过 for 循环都会重新分配 name 变量。所以最后,所有按钮都获得了name 在 for 循环中分配的最后一个值。为避免这种情况,您可以在您的 Lamba 表达式中使用默认关键字参数,如下所示:

user_button = Tkinter.Button(self.root,
                             text=name,
                             command=lambda name=name: self.a(name))

这会在每次循环中将name 变量的当前值绑定到lamba 的name 关键字参数,从而产生所需的效果。

【讨论】:

这不是 tkinter 问题,它是关于函数嵌套、闭包等的问题。它也完全存在于其他上下文中。尽管如此 +1,否则它会准确描述发生的情况。 @glglgl 你是 100% 正确的。不是我的最佳选择,将修改。 非常感谢您的回答。这使我免于搜索更多小时。 如果我们要执行多个函数怎么办? self.a 和 self.b 这对我有用,但我注意到 lambda 有很多像这样的奇怪事情。是否有理由需要 lambda?

以上是关于Tkinter 在循环中使用 lambda 分配按钮命令的主要内容,如果未能解决你的问题,请参考以下文章

tkinter 按钮回调中的 Lambda 函数

使用 Tkinter 在 while 循环中录制语音

Tkinter lambda 函数

在 Tkinter 主循环期间录制 OpenCV 视频

如何理解 lambda 中的闭包?

Python中带有lambda的tkinter按钮命令