3

当我单击由 for 循环创建的每个按钮时,我试图打印出按钮编号。以下是我尝试过的。

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 时,它会为 2 打印 1,2 ,依此类推?

4

4 回答 4

9

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

command = lambda j=i: myfunction(j)
于 2013-09-16T22:25:34.820 回答
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()
于 2013-04-18T05:09:04.790 回答
0

这是因为i在您的匿名函数中是指计数器变量,而不是值:

from __future__ import print_function

x = [lambda: print(i) for i in range(10)]

for f in x:
    f()

这会产生 10 个连续9s 的输出。

为了解决这个问题,你必须使用两个lambdas 和 shadowi第二个函数(它创建你的第一个函数):

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))
于 2013-04-18T04:36:10.250 回答
0

问题是 tk 中的 Button 命令忽略了任何参数,因此在 mycommand(data) 之类的数据被忽略。

我经常使用按钮,并决定将 tk Button 子类化以包含数据。我称它为 DataButton 并添加了一个数据成员(在本例中为索引号)。这样,当单击它时,它会传回其数据。(索引号)现在,只要我希望它保存诸如索引甚至消息之类的信息,我就会使用 DataButton。

于 2015-07-10T16:54:28.860 回答