如何在 for 中生成 lambda 函数
How to generate lambda functions within for
信息
- python 3
- tkinter
目标
我有一段代码,可以为我生成自定义菜单。现在我想在鼠标悬停在菜单中的单个按钮上时更改它们的颜色。
代码
for i in cmd:
button = Button([..set some stuff here..])
button.bind("<Enter>", lambda name: button.config(bg=hovercolor))
button.bind("<Leave>", lambda name: button.config(bg=color))
button.pack()
我的想法是将 ENTER 和 LEAVE 事件绑定到每个按钮。要让 lambda 函数工作,它需要一个名称(在本例中是名称,但我不关心名称)。
问题
如果鼠标悬停在我生成的菜单中的任何按钮上,最后一个按钮的颜色会改变。
我认为这是由 lambda 函数的名称引起的。每个按钮都会生成一个新的同名 lambda 函数,覆盖 python 环境中之前的 lambda 函数。
我正在搜索:
一种为 lambda 函数生成名称的方法
或
鼠标悬停在按钮上时更改颜色的另一种方法。
已解决
for i in cmd:
button = Button([..set some stuff here..])
button.bind("<Enter>", lambda name, button=button: button.config(bg=hovercolor))
button.bind("<Leave>", lambda name, button=button: button.config(bg=color))
button.pack()
发生这种情况的原因正如您所说,名称被覆盖并且 lambda 表达式全部 运行 在相同的变量上。
你可以做的是创建一个回调工厂,这样你就可以将名称传递给函数,函数将 return 调用的回调。
def create_callback(button, bg_color):
lambda x: button.config(bg=bg_color)
button.bind("<Enter>", create_callback(button, hovercolor))
问题是 button
的绑定。您的 lambda 表达式没有定义它,因此需要在外部范围(循环)中找到一个闭包。由于每次循环时值都会改变,当 lambda 函数为 运行 时,button
变量指向您创建的最后一个按钮,而不是它在定义 lambda 函数时指向的按钮。
您可以通过将每个按钮对象保存为默认参数来解决此问题:
button.bind("<Enter>", lambda name, button=button: button.config(bg=hovercolor))
button=button
参数使 button
成为 lambda 中的局部变量,因此更改外部定义无关紧要。无需关闭!
信息
- python 3
- tkinter
目标
我有一段代码,可以为我生成自定义菜单。现在我想在鼠标悬停在菜单中的单个按钮上时更改它们的颜色。
代码
for i in cmd:
button = Button([..set some stuff here..])
button.bind("<Enter>", lambda name: button.config(bg=hovercolor))
button.bind("<Leave>", lambda name: button.config(bg=color))
button.pack()
我的想法是将 ENTER 和 LEAVE 事件绑定到每个按钮。要让 lambda 函数工作,它需要一个名称(在本例中是名称,但我不关心名称)。
问题
如果鼠标悬停在我生成的菜单中的任何按钮上,最后一个按钮的颜色会改变。
我认为这是由 lambda 函数的名称引起的。每个按钮都会生成一个新的同名 lambda 函数,覆盖 python 环境中之前的 lambda 函数。
我正在搜索:
一种为 lambda 函数生成名称的方法
或
鼠标悬停在按钮上时更改颜色的另一种方法。
已解决
for i in cmd:
button = Button([..set some stuff here..])
button.bind("<Enter>", lambda name, button=button: button.config(bg=hovercolor))
button.bind("<Leave>", lambda name, button=button: button.config(bg=color))
button.pack()
发生这种情况的原因正如您所说,名称被覆盖并且 lambda 表达式全部 运行 在相同的变量上。
你可以做的是创建一个回调工厂,这样你就可以将名称传递给函数,函数将 return 调用的回调。
def create_callback(button, bg_color):
lambda x: button.config(bg=bg_color)
button.bind("<Enter>", create_callback(button, hovercolor))
问题是 button
的绑定。您的 lambda 表达式没有定义它,因此需要在外部范围(循环)中找到一个闭包。由于每次循环时值都会改变,当 lambda 函数为 运行 时,button
变量指向您创建的最后一个按钮,而不是它在定义 lambda 函数时指向的按钮。
您可以通过将每个按钮对象保存为默认参数来解决此问题:
button.bind("<Enter>", lambda name, button=button: button.config(bg=hovercolor))
button=button
参数使 button
成为 lambda 中的局部变量,因此更改外部定义无关紧要。无需关闭!