为什么我的按钮命令在我创建按钮时立即执行,而不是在我单击它时执行?
我的代码是:
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”,然后,当我按下按钮时什么也没有发生。
My code is:
from Tkinter import *
admin = Tk()
def button(an):
print(an)
print('het')
b = Button(admin, text='as', command=button('hey'))
b.pack()
mainloop()
The button doesn't work, it prints 'hey' and 'het' once without my command, and then, when I press the button nothing happens.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
考虑以下代码:
它的作用与此完全相同:
同样,如果您创建如下所示的绑定:
... 与此相同:
command
选项采用对函数的引用,该函数是一种奇特的说法是,您需要向其传递函数的名称。要传递引用,您必须仅使用名称,而不能使用括号或参数。例如:如果您想传递诸如“hey”之类的参数,则必须使用一些额外的代码:
button
函数,lambda
命令时,它会返回对所创建函数的引用,这意味着它可用于command
选项的值按钮。对于我来说,
lambda
是最简单的,因为它不需要像functools.partial
那样进行任何额外的导入,尽管有些人认为functools.partial
更容易理解。要创建一个使用参数调用
button
函数的 lambda 函数,您需要执行以下操作:您最终会得到一个功能上等效于的函数:
正如我之前所说,
lambda 返回对此无名函数的引用。由于引用是
command
选项所期望的,因此您可以在创建按钮时直接使用lambda
:此网站上有一个问题,其中有很多关于 lambda 的有趣评论, 一般来说。请参阅问题为什么 Python lambda 很有用?。同样的讨论有一个答案,展示了如何在需要时在循环中使用 lambda将变量传递给回调。
最后,请参阅 zone.effbot.org 文章标题为 Tkinter Callbacks 是一个很好的教程。 lambda 的覆盖范围相当精简,但其中的信息可能仍然有用。
Consider this code:
It does exactly the same as this:
Likewise, if you create a binding like this:
... it's the same as this:
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:If you want to pass a parameter such as "hey" you must use a little extra code:
button
function,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.For me,
lambda
is the simplest since it doesn't require any additional imports likefunctools.partial
does, though some people think thatfunctools.partial
is easier to understand.To create a lambda function that calls your
button
function with an argument you would do something like this:You end up with a function that is functionally equivalent to:
As I said earlier,
lambda
returns a reference to this nameless function. Since a reference is what thecommand
option expects you can uselambda
directly in the creation of the button: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.
Finally, see the zone.effbot.org article titled Tkinter Callbacks for a nice tutorial. The coverage of
lambda
is pretty lean, but the information there might still be useful.您需要创建一个不带参数的函数,可以将其用作命令:
请参阅 本文档。
You need to create a function without parameters that you can use as the command:
See the "Passing Argument to Callbacks" section of this document.
GUI 示例:
假设我有 GUI:
按下按钮时会发生什么
看到按下
btn
时,它会调用自己的函数,该函数与非常相似下面例子中的button_press_handle
:with:
你可以简单的认为
command
选项应该设置为,对我们想要调用的方法的引用,类似于callback中
button_press_handle
。按下按钮时调用方法(回调)
没有参数
因此,如果我想在按下按钮时
打印
某些内容,我需要设置:密切注意缺少 <代码>() 与
print
方法被省略,其含义是:“这是我希望您在按下时调用的方法名称但是不要这么称呼它然而,我没有为print
传递任何参数,因此它会打印在不带参数调用时打印的任何内容。带有参数
现在,如果我还想在按下按钮时将参数传递给我想要调用的方法,我可以这样做使用匿名函数,可以使用 lambda 语句创建,在本例中为
print
内置方法,如下所示:按下按钮时调用多个方法
不带参数
您还可以使用
lambda
语句来实现但这被认为是不好的做法,因此我不会将其包含在这里。好的做法是定义一个单独的方法multiple_methods
,它调用所需的方法,然后将其设置为按钮按下的回调:With Argument(s )
为了将参数传递给调用其他方法的方法,请再次使用 lambda 语句,但首先:
然后设置:
从回调返回对象
还 进一步注意
回调
不能真正return
,因为它仅在button_press_handle
内部使用callback()
调用,而不是return callback()
。它确实返回
,但不在该函数之外的任何地方。因此,您应该修改当前范围内可访问的对象。完整示例 全局对象修改
下面的示例将调用一个方法,该方法会在每次按下按钮时更改
btn
的文本:镜像
Example GUI:
Let's say I have the GUI:
What Happens When a Button Is Pressed
See that when
btn
is pressed it calls its own function which is very similar tobutton_press_handle
in the following example:with:
You can simply think that
command
option should be set as, the reference to the method we want to be called, similar tocallback
inbutton_press_handle
.Calling a Method (a Callback) When the Button is Pressed
Without arguments
So if I wanted to
print
something when the button is pressed I would need to set:Pay close attention to the lack of
()
with theprint
method which is omitted in the meaning that: "This is the method's name which I want you to call when pressed but don't call it just this very instant." However, I didn't pass any arguments for theprint
so it printed whatever it prints when called without arguments.With Argument(s)
Now If I wanted to also pass arguments to the method I want to be called when the button is pressed I could make use of the anonymous functions, which can be created with lambda statement, in this case for
print
built-in method, like the following:Calling Multiple Methods when the Button Is Pressed
Without Arguments
You can also achieve that using
lambda
statement but it is considered bad practice and thus I won't include it here. The good practice is to define a separate method,multiple_methods
, that calls the methods wanted and then set it as the callback to the button press:With Argument(s)
In order to pass argument(s) to method that calls other methods, again make use of
lambda
statement, but first:and then set:
Returning Object(s) From the Callback
Also further note that
callback
can't reallyreturn
because it's only called insidebutton_press_handle
withcallback()
as opposed toreturn callback()
. It doesreturn
but not anywhere outside that function. Thus you should rather modify object(s) that are accessible in the current scope.Complete Example with global Object Modification(s)
Below example will call a method that changes
btn
's text each time the button is pressed:Mirror
当引擎在“... command = ...”行赋值时,它会评估函数的结果。
“command”期望返回一个函数,这就是为什么使用 lambda 可以完成这项工作,因为它是创建一个匿名函数,该函数在评估期间返回到“命令”。
您也可以编写自己的函数,它也可以完成这项工作。
这是使用 lambda 和不使用 lambda 的示例:
The engine evaluates the result of the function when it is assigning the value at the line "... command = ..."
The "command" expects a function to be returned, that's why using a lambda can do the job because it is creating an anomymous function that is returned to the "command" during evaluation.
You can also code your own function, it will do the job also.
this is an example with lambda and without lambda:
我认为解决这个问题的最好方法是使用 lambda 函数。
如果你不想使用 command 关键字,你可以使用 .bind() 方法来代替:
使用拥有你想要调用的子函数(至少 1 个参数)的母函数(无参数)是愚蠢的。
只是与您分享,这是我的程序之一:
就是这样。
I think the best way to solve this problem is to use a lambda function.
If you don't want to use the command keyword, you can use the .bind() method instead:
Using a mother function (no parameter) which owns the child function (at least 1 parameter) you want to call is stupid.
Just to share with you, this is one of my program:
That's it.