我一直在使用Tkinter在Python中编写一个很长的GUI。我不明白的一件事是为什么我不能将事件绑定到循环中的小部件。在下面的代码中,如果我手动(注释掉代码)但在for循环中没有绑定,则绑定很有效。我做错了吗?
导入Tkinter
root = Tkinter.Tk()
b1 = Tkinter.Button(root, text="Button 1")
b1.pack()
b1.focus_set()
b2 = Tkinter.Button(root, text="Button 2")
b2.pack()
b3 = Tkinter.Button(root, text="Button 3")
b3.pack()
def up_and_down(*buttons):
for i in range(len(buttons)-1):
buttons[i].bind("<Down>", lambda x: buttons[i+1].focus_set())
for i in range(1, len(buttons)):
buttons[i].bind("<Down>", lambda x: buttons[i-1].focus_set())
'''
buttons[0].bind("<Down>", lambda x: buttons[1].focus_set())
buttons[1].bind("<Down>", lambda x: buttons[2].focus_set())
buttons[1].bind("<Up>", lambda x: buttons[0].focus_set())
buttons[2].bind("<Up>", lambda x: buttons[1].focus_set())
'''
up_and_down(b1, b2, b3)
root.mainloop()
答案 0 :(得分:3)
你的闭包(lambdas)没有像你期望的那样工作。它们保留对i
的引用,它随着循环的迭代而变异,最后来自同一循环的所有lambda引用相同的单个最后一个按钮。
以下是行为的说明:
>>> k = []
>>> for i in range(5):
... k.append(lambda: i)
>>> k[0]()
4
>>> [f() for f in k]
[4, 4, 4, 4, 4]
答案 1 :(得分:3)
您可以使用以下方法解决问题:
for i in range(len(buttons)-1):
buttons[i].bind("<Down>", lambda x, i=i: buttons[i+1].focus_set())
for i in range(1, len(buttons)):
buttons[i].bind("<Down>", lambda x, i=i: buttons[i-1].focus_set())
注意i=i
闭包的lambda
参数。