我的代码是:
from Tkinter import *
admin = Tk()
def button(an):
print(an)
print('het')
b = Button(admin, text='as', command=button('hey'))
b.pack()
mainloop()
该按钮不起作用,它会在没有我的命令的情况下打印“hey”和“het”一次,然后,当我按下按钮时什么也没有发生。
最佳答案
考虑这段代码:
b = Button(admin, text='as', command=button('hey'))
它的作用与此完全相同:
result = button('hey')
b = button(admin, text='as', command=result)
同样,如果您创建这样的绑定(bind):
listbox.bind("<<ListboxSelect>>", some_function())
...与此相同:
result = some_function()
listbox.bind("<<ListboxSelect>>", result)
command
选项采用对函数的引用,这是一种奇特的方式,表示您需要向其传递函数的名称。要传递引用,您必须仅使用名称,而不能使用括号或参数。例如:
b = Button(... command = button)
如果你想传递一个参数,比如“hey”,你必须使用一些额外的代码:
- 您可以创建一个无需参数即可调用的中间函数,然后该函数调用您的
button
函数, - 您可以使用
lambda
创建所谓的匿名函数。从各方面来说,它都是一个函数,只是它没有名称。当您调用lambda
命令时,它会返回对所创建函数的引用,这意味着它可用于command
选项的值按钮。 - 您可以使用functools.partial
对我来说,lambda
是最简单的,因为它不需要像 functools.partial
那样的任何额外导入,尽管有些人认为 functools.partial
更容易理解。
要创建一个使用参数调用 button
函数的 lambda 函数,您需要执行以下操作:
lambda: button('hey')
您最终得到的函数在功能上等同于:
def some_name():
return button('hey')
正如我之前所说,lambda
返回对此无名函数的引用。由于引用是 command
选项所期望的,因此您可以在创建按钮时直接使用 lambda
:
b = Button(... command = lambda: button('hey'))
这个网站上有一个问题,其中有很多关于 lambda 的有趣评论。查看问题Why Python lambdas are useful? 。同样的讨论有an answer that shows how to use lambdas in a loop当您需要将变量传递给回调时。
最后,请参阅zone.effbot.org文章标题为Tkinter Callbacks一个很好的教程。 lambda
的覆盖范围相当精简,但其中的信息可能仍然有用。
关于python - 为什么我的按钮的命令在我创建按钮时立即执行,而不是在我单击它时执行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47041755/