tkinter 按钮回调中的 Lambda 函数

Posted

技术标签:

【中文标题】tkinter 按钮回调中的 Lambda 函数【英文标题】:Lambda functions in tkinter button callbacks 【发布时间】:2021-08-27 09:34:32 【问题描述】:

我非常了解 lambda 函数。话虽如此,我有一个 Python tkinter GUI,它打开一个单独的“选项”窗口 - 用户输入文本,然后可以单击“设置”按钮,或者按绑定到同一个按钮的 Enter,设置文本并返回主窗口。

看来,回车键的绑定代码需要我告诉 lambda 函数我正在传递输入(据我了解,它们是这样工作的,这也是我所期望的)。

但是 - 按钮的“command=”代码只有在我包含它时才有效,我不明白。

这是代码 - 我的问题是 - 为什么在按钮情况下我不告诉 lambda 函数我将变量传递给函数,但在输入键绑定中我做了?

    saveBtn = tk.Button(saveWindow,text='Save', width=10,**command=lambda: pressed(fName)**)
    saveBtn.grid(row=2,column=2)        
    saveWindow.bind('<Return>',**lambda x: pressed(fName)**)

【问题讨论】:

当 tkinter 调用你的 command 时,你已经知道用户按下了按钮。但是如果你绑定到类似"&lt;Key&gt;" 的东西,你可能想知道按下了哪个键,所以当tkinter 调用你的函数时,它会使用event 参数调用它。尝试打印出来自己看看 tkinter 的作者决定该按钮将在没有任何参数的情况下运行function()。他们决定 bind 将运行 function(event) 并提供额外信息。在其他 GUI 框架中 - 例如 PyQtPYGTK - 它可能会以不同的方式工作,并且按钮也可能会发送一些额外的信息来运行。 @furas: “tkinter 的作者决定按钮将在没有任何参数的情况下运行 function()。” 并不完全正确。绑定需要一个callable,并且python 的规则不允许你指定一个callable,除非你使用lambdafunctools.partial 之类的东西。这不是真正的 tkinter 东西,而是 python 的东西。 @BryanOakley 我并没有考虑如何创建可调用对象,但我在想mainloop 将如何执行分配的功能 - 这是 tkinter(或 tcl/tk)的作者决定 mainloopcommand= 将在不带参数的情况下运行此函数,但 bind 使用 event 运行。 【参考方案1】:

看来,回车键的绑定代码需要我告诉 lambda 函数我正在传递输入(据我了解,它们是这样工作的,这也是我所期望的)。

不完全是。 bind 命令要求您将 callable 传递给它,并且该可调用对象必须接受单个位置参数才能接收事件对象。 bind 命令不关心可调用对象是函数、lambda 还是其他任何东西。它必须是可调用的并接受一个参数。

如果您需要传入其他参数,则需要定义一个负责处理参数的可调用对象。最常见的方法是使用lambdafunctools.partial,它可以让您创建一个新的匿名可调用函数。

...为什么在按钮的情况下我没有告诉 lambda 函数我将变量传递给函数,但在输入键绑定中我做了?

简短的回答是“这就是它们被定义为工作的方式”。按钮的command 将在没有任何参数的情况下被调用,bind 调用的函数将被传递一个代表事件的参数。

我想这是因为通常按钮的命令不需要事件参数,因为事件在很大程度上是无关紧要的。另一方面,绑定函数通常需要事件参数。

【讨论】:

以上是关于tkinter 按钮回调中的 Lambda 函数的主要内容,如果未能解决你的问题,请参考以下文章

python tkinter, 通过lambda表达式传递参数到按钮的点击事件函数

Tkinter 按钮回调缺少它包含的参数[重复]

Tkinter lambda 函数

Tkinter Button按钮组件如何调用一个可以传入参数的函数

tkinter - Button

Python中带有lambda的tkinter按钮命令