2013-04-18 111 views
2

我试图打印出按钮编号,当我点击由循环创建的每个按钮。以下是我所尝试过的。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,等等?

回答

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() 
0

这是因为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)) 
7

简单的解决方法是每次创建lambda函数时用当前值i初始化lambda函数。这可以使用另一个虚拟变量j的Python默认值完成。

command = lambda j=i: myfunction(j) 
0

问题是tk中的Button命令忽略了任何像mycommand(data)这样的数据被忽略的参数。

我使用的按钮相当多,并决定继承一个tk Button来包含数据。我称它为一个DataButton并添加了一个数据成员(在这种情况下是一个索引号)。这种方式点击时,它会传回其数据。 (索引号)现在我使用DataButton,只要我想要它像索引或甚至消息一样保存信息。