How to prevent closing of parent window before child window is closed How to prevent closing of parent window before child window is closed tkinter tkinter

How to prevent closing of parent window before child window is closed


Lets say that if the child window exists, trying to close the parent window will put it into focus, this would require a few changes:

  1. override the close protocol with .protocol("WM_DELETE_WINDOW") so it checks for a child window.
  2. Keep a reference to a child window
class MainWindow(Tk):    def __init__(self):        Tk.__init__(self)        Button(self, text="hello there", command=self.open_window).grid(row=0, column=0)        self.protocol("WM_DELETE_WINDOW", self.try_to_close)        self.win = None    def open_window(self):        if self.win is None or not self.win.winfo_exists():            self.win = Window(self)        self.win.lift(self)        self.win.focus_set()    def try_to_close(self):        if self.win is not None and self.win.winfo_exists():            self.win.lift()        else:            self.destroy()


For windows you can use:

root.protocol("WM_DELETE_WINDOW", your_function_here)

I don't know about other operating systems as I have not tested it on anything other than windows.

Works fine in a class as well.

self.root.protocol("WM_DELETE_WINDOW", self.your_method_here)

I have added some code to your post to illustrate its use. Note when you press the X button the program will rune the close_program method.

Edit: Without being able to test on Mac I have added what I think will fix your problem. I have added an if statement in the close_program method to check if the top level exist before attempting to close.

Update: I added a check for the variable win to deal with possible errors if toplevel was never opened but still trying to close root window.

from tkinter import *class Window(Toplevel):    def __init__(self, master):        Toplevel.__init__(self)        self.protocol("WM_DELETE_WINDOW", self.close_program)    def close_program(self):        print ("destroying Window")        self.destroy()class MainWindow(Tk):    def __init__(self):        Tk.__init__(self)        Button(self, command=self.open_window).grid(row=0, column=0)        self.protocol("WM_DELETE_WINDOW", self.close_program)    def open_window(self):        global win        win = Window(self)        win.grab_set()    def close_program(self):        if 'win' in globals():            if win.winfo_exists() == 1:                print("top level still active")            else:                print("destroying MainWindow")                self.destroy()        else:            print("destroying MainWindow")            self.destroy()app = MainWindow()app.mainloop()