Python Tkinter按钮回调
问题描述:
我试图打印出按钮编号,当我点击由循环创建的每个按钮。以下是我所尝试过的。Python Tkinter按钮回调
import Tkinter as tk
root=tk.Tk()
def myfunction(a):
print a
for i in range(10):
tk.Button(root,text='button'+str(i),command=lambda:myfunction(i)).place(x=10,y=(10+(25*i)))
root.mainloop()
但不是打印出每个按钮的号码,它实际上每次给我最后一个按钮的号码。有什么我可以做,所以当我点击按钮1,它会打印1,2 2,等等?
答
Blender的答案是一个聪明的解决方案,但如果你被函数抽象抛弃,这里是另一种可能的方式来做到这一点。它真的只是创建一个映射,保存在buttons
,从Button
小部件保存到它们的正确数字。
import Tkinter as tk
root = tk.Tk()
def myfunction(event):
print buttons[event.widget]
buttons = {}
for i in range(10):
b = tk.Button(root, text='button' + str(i))
buttons[b] = i # save button, index as key-value pair
b.bind("<Button-1>", myfunction)
b.place(x=10,y=(10+(25*i)))
root.mainloop()
答
这是因为i
在你的匿名函数是指计数器变量,而不是价值:
from __future__ import print_function
x = [lambda: print(i) for i in range(10)]
for f in x:
f()
由此产生的10角连续9
秒的输出。
要解决这个问题,你必须使用两个lambda
S和与秒功能阴影i
(产生你的第一个功能):
from __future__ import print_function
x = [(lambda i: (lambda: print(i)))(i) for i in range(10)]
for f in x:
f()
虽然在这一点上,你会会更好只是让一个名为功能:
def my_command(i):
def inner_function():
return my_function(i)
return inner_function
,并用它是这样的:
tk.Button(root, text='button' + str(i), command=my_command(i))
答
简单的解决方法是每次创建lambda函数时用当前值i初始化lambda函数。这可以使用另一个虚拟变量j的Python默认值完成。
command = lambda j=i: myfunction(j)
答
问题是tk中的Button命令忽略了任何像mycommand(data)这样的数据被忽略的参数。
我使用的按钮相当多,并决定继承一个tk Button来包含数据。我称它为一个DataButton并添加了一个数据成员(在这种情况下是一个索引号)。这种方式点击时,它会传回其数据。 (索引号)现在我使用DataButton,只要我想要它像索引或甚至消息一样保存信息。