如何重用逻辑来处理 Python 的 tkinter GUI 中的按键和按钮单击?

2023-12-14

我有这个代码:

from tkinter import *
import tkinter as tk

class App(tk.Frame):
    def __init__(self, master):
        def print_test(self):
            print('test')

        def button_click():
            print_test()

        super().__init__(master)
        master.geometry("250x100")
        entry = Entry()

        test = DoubleVar()
        entry["textvariable"] = test
        entry.bind('<Key-Return>', print_test)
        entry.pack()
        button = Button(root, text="Click here", command=button_click)
        button.pack()

root = tk.Tk()
myapp = App(root)
myapp.mainloop()

单击按钮会抛出:

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.3056.0_x64__qbz5n2kfra8p0\lib\tkinter\__init__.py", line 1921, in __call__
    return self.func(*args)
  File "[somefilepath]", line 10, in button_click
    print_test()
TypeError: App.__init__.<locals>.print_test() missing 1 required positional argument: 'self'

按下时Enter当 Entry 小部件工作时,它会打印:test

See:

enter image description here

现在如果我放弃(self) from def print_test(self):, as 类型错误:button_click() 缺少 1 个必需的位置参数:'self'显示,该按钮有效,但按下EnterEntry 小部件中的命令不会触发该命令,但会引发另一个异常:

enter image description here

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.3056.0_x64__qbz5n2kfra8p0\lib\tkinter\__init__.py", line 1921, in __call__
    return self.func(*args)
TypeError: App.__init__.<locals>.print_test() takes 0 positional arguments but 1 was given

如何编写代码,使得按钮单击事件和按 Enter 键都会触发打印命令?


调用按钮单击的命令回调时不带参数,因为没有更多相关信息:按钮的点是只有一种“方式”来点击它。

但是,按键是事件,因此,按键绑定的回调会传递一个表示的参数事件 (not与编写回调的上下文有关的任何事情)。

对于按键处理程序,通常不需要考虑事件中的任何信息。因此,回调可以简单地将此参数默认为None,然后忽略它:

def print_test(event=None):
    print('test')

现在,它可以直接用作按键绑定和按钮按下的处理程序。请注意,这有效非常好作为顶级函数,即使在App类,因为代码不使用任何功能 from App.

另一种方法是反转委托逻辑。在原始代码中,按钮处理程序尝试委托给按键处理程序,但不能,因为它没有要传递的事件对象。虽然它可以通过None或其他一些无用的对象(因为按键处理程序实际上并不关心该事件),这有点难看。更好的方法是相反地委托:使用按键处理程序discard传递给它的事件,因为它委托给按钮处理程序(执行硬编码操作)。

Thus:

from tkinter import *
import tkinter as tk

def print_test():
    print('test')

def enter_pressed(event):
    print_test()

class App(tk.Frame):
    def __init__(self, master):
        super().__init__(master)
        master.geometry("250x100")

        entry = Entry()
        test = DoubleVar()
        entry["textvariable"] = test
        entry.bind('<Key-Return>', enter_pressed)
        entry.pack()

        button = Button(root, text="Click here", command=print_test)
        button.pack()


root = tk.Tk()
myapp = App(root)
myapp.mainloop()
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何重用逻辑来处理 Python 的 tkinter GUI 中的按键和按钮单击? 的相关文章

随机推荐