Skip to main content
 首页 » 编程设计

python之以编程方式按下工具栏上的 `X` 按钮

2025年05月04日24TianFang

我知道我可以使用 protocol("WM_DELETE_WINDOW", do_something) 拦截按下 X 按钮,但是我很难弄清楚如何激活此按钮或至少按下此按钮时触发的协议(protocol)。

情况是这样的。我有2节课。我的主要 Tk 类和我的 Menu 类。当我设置命令以使用菜单中的 exit 按钮关闭程序时,我希望此按钮执行与 上的 X 按钮完全相同的操作>Tk 类。

现在我知道我可以简单地调用传递给菜单类的 Controller ,然后调用我构建的方法来处理关闭事件,但是我正在尝试以不需要的方式构建这个菜单类从菜单类中执行此操作。这将允许我在我构建的任何应用程序上使用菜单类,几乎不需要编辑。

我无法找到告诉我如何以编程方式激活 "WM_DELETE_WINDOW" 协议(protocol)的帖子或文档。

如果不清楚我想要什么,这里有一张图片。简单地说,我希望退出按钮的功能与 X 按钮的功能完全相同。

主类:

import tkinter as tk 
import PIP_MENU 
 
 
class PIP(tk.Tk): 
    def __init__(self): 
        super().__init__() 
        PIP_MENU.start(self) 
        self.protocol("WM_DELETE_WINDOW", self.handle_close) 
 
    def handle_close(self): 
        print("Closing") 
        self.quit() 
 
if __name__ == '__main__': 
    PIP().mainloop() 

单独的 .py 文件中的菜单类:

import tkinter as tk 
 
class Menu(tk.Menu): 
    def __init__(self, controller): 
        super().__init__() 
        self.controller = controller 
        controller.config(menu=self) 
        file_menu = tk.Menu(self, tearoff=0) 
        self.add_cascade(label="File", menu=file_menu) 
        file_menu.add_command(label="Exit", command=self.handle_exit) 
 
    def handle_exit(self): 
        # What can I do here that will be handled by 
        # protocol "WM_DELETE_WINDOW" of the main class? 
        # All I can find is destroy() and quit() 
        # But both of these do not get handled by "WM_DELETE_WINDOW". 
 
def start(controller): 
    Menu(controller) 

请您参考如下方法:

I have not been able to find a post or some documentation that tells me how I can programmatically active the "WM_DELETE_WINDOW" protocol.

你不能。根据定义,WM_DELETE_WINDOW 协议(protocol)来自窗口管理器。

捕获协议(protocol)处理程序旨在让您有机会覆盖其行为。无论应用程序如何销毁,它都不是一种触发某些代码的方法。如果您想在窗口被销毁时运行一些代码,无论是通过用户单击窗口框架上的控件还是通过其他方式,正确的方法是绑定(bind)到 <Destroy>。根窗口上的事件。

您必须小心,因为每个小部件都会触发根窗口上的任何绑定(bind)。因此,您的绑定(bind)应该只在 event.widget 时运行。与根窗口相同。

以下示例说明了该技术。有一种方法handle_close每当窗口被销毁时都会调用它。您是通过单击窗口框架上的控件来关闭窗口,还是单击“关闭我!”按钮,代码仍然运行。

import tkinter as tk 
 
 
class Example(tk.Tk): 
    def __init__(self): 
        super().__init__() 
        self.bind("<Destroy>", self.handle_close) 
 
        button = tk.Button(self, text="Close me!", command=self.destroy) 
        button.pack() 
 
    def handle_close(self, event): 
        if event.widget == self: 
            print("Closing") 
        self.quit() 
 
example = Example() 
example.mainloop()