为什么在声明时命令绑定到按钮或事件执行? [英] Why is the command bound to a Button or event executed when declared?
问题描述
我的代码是:
from Tkinter import *
admin = Tk()
def button(an):
print an
print 'het'
b = Button(admin, text='as', command=button('hey'))
b.pack()
mainloop()
按钮不起作用,它会在没有我的命令的情况下打印一次嘿"和het",然后当我按下按钮时什么也没有发生.
The button doesn't work, it prints 'hey' and 'het' once without my command, and then, when I press the button nothing happens.
推荐答案
考虑以下代码:
b = Button(admin, text='as', command=button('hey'))
它的作用与此完全相同:
It does exactly the same as this:
result = button('hey')
b = button(admin, text='as', command=result)
同样,如果您创建这样的绑定:
Likewise, if you create a binding like this:
listbox.bind("<<ListboxSelect>>", some_function())
...和这个一样:
result = some_function()
listbox.bind("<<ListboxSelect>>", result)
command
选项引用一个函数,这是一种奇特的方式,表示您需要将函数的名称传递给它.要传递引用,您必须仅使用名称,而不能使用括号或参数.例如:
The command
option takes a reference to a function, which is a fancy way of saying you need to pass it the name of the function. To pass a reference you must use the name only, without using parenthesis or arguments. For example:
b = Button(... command = button)
如果你想传递一个参数,比如嘿"你必须使用一些额外的代码:
If you want to pass a parameter such as "hey" you must use a little extra code:
- 您可以创建一个可以在没有参数的情况下调用的中间函数,然后调用您的
button
函数, - 您可以使用
lambda
来创建所谓的匿名函数.在任何方面它都是一个函数,除了它没有名字.当您调用lambda
命令时,它会返回一个 reference 到创建的函数,这意味着它可以用于command
选项的值按钮. - 您可以使用functools.partial
- You can create an intermediate function that can be called without your argument and which then calls your
button
function, - You can use
lambda
to create what is referred to as an anonymous function. In every way it's a function except it doesn't have a name. When you call thelambda
command it returns a reference to the created function, which means it can be used for the value of thecommand
option to the button. - You can use functools.partial
对我来说,lambda
是最简单的,因为它不需要像 functools.partial
那样的任何额外导入,尽管有些人认为 functools.partial
更容易理解.
For me, lambda
is the simplest since it doesn't require any additional imports like functools.partial
does, though some people think that functools.partial
is easier to understand.
要创建一个使用参数调用 button
函数的 lambda 函数,您可以执行以下操作:
To create a lambda function that calls your button
function with an argument you would do something like this:
lambda: button('hey')
你最终得到一个功能等同于的函数:
You end up with a function that is functionally equivalent to:
def some_name():
return button('hey')
正如我之前所说,lambda
返回对这个无名函数的引用.由于引用是 command
选项所期望的,因此您可以在创建按钮时直接使用 lambda
:
As I said earlier, lambda
returns a reference to this nameless function. Since a reference is what the command
option expects you can use lambda
directly in the creation of the button:
b = Button(... command = lambda: button('hey'))
这个网站上有一个问题,有很多关于 lambda 的有趣评论,总的来说.请参阅问题为什么 Python lambda 有用?.同样的讨论有一个显示如何在需要时在循环中使用 lambdas 的答案将变量传递给回调.
There's a question on this site that has a lot of interesting comments about lambda, in general. See the question Why Python lambdas are useful?. That same discussion has an answer that shows how to use lambdas in a loop when you need to pass in a variable to the callback.
最后,请参阅标题为 effbot.org 上的 Tkinter 回调 的部分,以获得不错的教程.lambda 的覆盖面相当简陋,但那里的信息可能仍然有用.
Finally, see the section titled Tkinter Callbacks on effbot.org for a nice tutorial. The coverage of lambda is pretty lean but the information there might still be useful.
这篇关于为什么在声明时命令绑定到按钮或事件执行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!