【问题标题】:How to close main Tkinter window from pop up window in python?如何从python中的弹出窗口关闭主Tkinter窗口?
【发布时间】:2020-09-08 15:18:04
【问题描述】:

我有一个主 tkinter 窗口,它启动多个弹出窗口。我正在尝试通过按弹出窗口中的叉号或按退出来关闭所有窗口。我有以下代码,通过按退出或十字键仅关闭弹出窗口,但不关闭主窗口。如何重构代码以实现所需的输出。

import tkinter as tk
from tkinter import *
      
class myclass:
    def __init__(self,master):
        self.master             = master      
        self.button            = tk.Button(self.master, text = "Function", command = self.launchFunc)        
        self.button.place(width=160,height=50, x=20, y=20)                
        self.quit         = tk.Button(self.master, text = "Quit", command = self.close_windows)  
        self.quit.place(width=160,height=50, x=20, y=80)
       
    def close_windows(self):
        self.master.destroy()
    
    def launchFunc(self):
        self.top                = tk.Toplevel(self.master)
        self.top.transient(self.master)        
        self.app                = funcClass(self.top)

class funcClass:
    def __init__(self, master):
        self.master1            = master
        self.quit         = tk.Button(self.master1, text = "Quit", command = self.close_windows)  
        self.quit.place(width=160,height=50, x=20, y=20)  
                      
    def close_windows(self):
        self.a    = myclass(self.master1) 
        self.a.close_windows()
        
if __name__ == "__main__":
    root = tk.Tk()
    myclass = myclass(root)
    root.mainloop()

请指导我。谢谢

【问题讨论】:

  • 为什么funcClass.close_windows() 会创建myclass 的新实例?您已经拥有这样一个实例(在self.master1 中),并且它具有正确的master 值来关闭根窗口。

标签: python-3.x tkinter


【解决方案1】:

您需要注册一个回调函数,当点击标题栏上的X 按钮时,使用protocol() 函数将执行该回调函数。您可以对Quit 按钮使用相同的功能。然后关闭回调函数内的root窗口:

class funcClass:
    def __init__(self, master):
        self.master1 = master
        self.quit = tk.Button(self.master1, text="Quit", command=self.close_windows)  
        self.quit.place(width=160, height=50, x=20, y=20)
        # for 'X' button in title bar
        master.protocol('WM_DELETE_WINDOW', self.close_windows) 
                      
    def close_windows(self):
        # self.master1 is the toplevel
        # so self.master1.master is the root window
        self.master1.master.destroy()

【讨论】:

  • 感谢大家的回复。 @acw1668 的回答成功了。我也很容易理解
【解决方案2】:

我建议您使用 simpledialog.Dialog 作为基类制作您自己的弹出窗口,您可以将这样的特殊指令传递给它。

它需要扩展基类并运行 super().init 并传递 parent 和 title 参数,以便正确构建弹出窗口。

class MyPopup(simpledialog.Dialog):
    def __init__(self, parent, title, superClose)
        self.superClose = superClose
        super().__init__(parent, title)

我添加了“superClose”参数以将其保存以备后用。 然后,我们重写该类的 destroy 方法以运行传递的参数。

def destroy(self):
    super().destroy()
    self.superClose()

super().destroy() 将运行原始版本的 destroy 方法,然后我们运行我们之前传递的保存的参数。

制作一些关闭事物的功能:

def closeOthers():
    <go through all your popups you want closed and close them>

然后让弹出窗口出现:

MyPopup(root, "Title", closeOthers)

当那个被销毁时,它也会调用那个函数。

要自定义该弹出窗口,请覆盖 body 方法。 (您不需要运行 super().body())这是您应该为弹出窗口添加所有 tkinter 小部件的地方。

还有几点需要了解: 这些将在底部附近有一个框架,默认情况下为您提供 OK 和 Cancel 按钮,调用 ok() 和 cancel() (您可以覆盖它们以选择它们做什么)并将 Enter 和 Escape 绑定到这些函数。如果你不想要这个,或者这个改变了什么,覆盖 buttonbox 方法。 cancel 函数也调用了 destroy 方法,它也会运行你的 superClose 方法。如果您希望取消按钮(和转义键)只是自行关闭而不运行 superClose,请使用以下代码覆盖它:

def cancel(self, event=None):
    if self.parent is not None:
        self.parent.focus_set()
    self.initial_focus = None
    Toplevel.destroy(self)

如果你对所有关闭如何运行 superClose 没问题,你也可以改写 apply(self)。每次弹出窗口被销毁后,这将使那里的所有内容都运行。

def apply(self):
    self.superClose()

它也不需要 super() 调用。

我希望这会有所帮助。如果您还有其他问题等,请告诉我们。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多