python - 为什么我的按钮的命令在我创建按钮时立即执行,而不是在我单击它时执行?

标签 python tkinter callback

我的代码是:

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/

相关文章:

python - 使用 Python 在 3D 中显示三角形

python - 禁用、隐藏或删除 Tkinter 中的关闭 "X"按钮

python - 在 tkinter 中仅选择文本而不是整行

c++ - 在类 Base 中实现函数的最有效方法

vba - VBA 中的自定义回调

php - 雅虎回调域问题

Python - 将 XLSX 转换为 PDF

python - RGB Int 到 RGB - Python

python - 如何在python中生成具有两个节点之间的长最短路径的有向无环图

python - 如何通过按下按钮隐藏框架的一部分