0
votes

If I create a Toplevel popup window in a tkinter application, when I close the main root window all sub windows are closed.

With the following code, if I open up two successive Toplevel windows, I can close "Window One" but "Window Two" stays open.

#!/usr/bin/env python3

import tkinter as tk
import tkinter.ttk as ttk

def main():
    root = tk.Tk()
    root.geometry("600x300")
    root.title("Main Window")
    app = Application(root)
    app.mainloop()

def window_one():
    window_one = WindowOne()
    window_one.geometry("450x200")
    window_one.title('Window One')

def window_two():
    window_two = WindowTwo()
    window_two.geometry("200x100")
    window_two.title('Window Two')


class Application(ttk.Frame):
    
    def __init__(self, master= None, *args, **kwargs):
        super().__init__(master = master)
        self.pack()
        self.create_widgets()
    
    def create_widgets(self):
        button1 = ttk.Button(self, text = "Click Here", command = window_one)
        button1.pack()


class WindowOne(tk.Toplevel):

    def __init__(self, master= None, *args, **kwargs):
        super().__init__(master = master)
        self.create_widgets()
    
    def create_widgets(self):
        button1 = ttk.Button(self, text = "Click Here", command = window_two)
        button1.pack()


class WindowTwo(tk.Toplevel):

    def __init__(self, master= None, *args, **kwargs):
        super().__init__(master = master)
        self.create_widgets()
    
    def create_widgets(self):
        button1 = ttk.Button(self, text = "$$$")
        button1.pack()

if __name__ == "__main__":
    main()

How can I code this to make Window Two dependent on Window One so that if I close "Window One", "Window Two" also closes, mimicking the behaviour of the main root window?

1

1 Answers

0
votes

You can make Window One the parent of Window Two:

def window_two(parent):
    window_two = WindowTwo(parent) # pass parent to WindowTwo
    window_two.geometry("200x100")
    window_two.title('Window Two')

...

class WindowOne(tk.Toplevel):

    def __init__(self, master= None, *args, **kwargs):
        super().__init__(master = master)
        self.create_widgets()
    
    def create_widgets(self):
        button1 = ttk.Button(self, text = "Click Here", command = lambda: window_two(self)) # pass self to `window_two()`
        button1.pack()

Update: if you want to close Window One when Window Two is closed, you can use self.protocol("WM_DELETE_WINDOW", ...):

class WindowTwo(tk.Toplevel):

    def __init__(self, master= None, *args, **kwargs):
        super().__init__(master = master)
        self.create_widgets()
        self.protocol("WM_DELETE_WINDOW", self.on_destroy)
    
    def create_widgets(self):
        button1 = ttk.Button(self, text = "$$$")
        button1.pack()

    def on_destroy(self):
        self.master.destroy() # close parent window
        self.destroy() # close itself

or bind <Destroy> event to a callback to close the parent window:

class WindowTwo(tk.Toplevel):

    def __init__(self, master= None, *args, **kwargs):
        super().__init__(master = master)
        self.create_widgets()
        self.bind("<Destroy>", self.on_destroy)
    
    def create_widgets(self):
        button1 = ttk.Button(self, text = "$$$")
        button1.pack()

    def on_destroy(self, event):
        self.master.destroy() # close parent window