1

I have a tkinter application with two windows: A MainWindow that is created on startup, and a ChildWindow which is opened after clicking a button.

The ChildWindow should close itself if the user presses a button. However, when I try calling frame.quit, it terminates the entire application instead.

import tkinter as tk

class ChildWindow:
    def __init__(self, master):
        self.top = tk.Toplevel(master)
        self.frame = tk.Frame(self.top)
        self.frame.pack()
        # BUG: Clicking "Close" will fully exit application
        self.close_button = tk.Button(self.frame, text="Close", command=self.frame.quit)
        self.close_button.pack()

class MainWindow:
    def __init__(self, master):
        self.master = master
        self.frame = tk.Frame(self.master)
        self.about_button = tk.Button(self.frame, text="Open child window", command=self._open_child_window)
        self.about_button.pack()
        self.frame.pack()

    def _open_child_window(self):
        self.about_window = ChildWindow(self.master)

root = tk.Tk()
lf = MainWindow(root)
root.mainloop()

Screenshots:

MainWindow ChildWindow

Why does frame.quit exit my application? How can I close the child window without exiting?

Stevoisiak
  • 23,794
  • 27
  • 122
  • 225
  • 4
    You're using the wrong method. Use `destroy` instead of `quit`. – Aran-Fey Feb 15 '18 at 21:42
  • I think this question should be the one that it is duplicate of now, as this is easier to understand. – Nae Feb 16 '18 at 12:26
  • Run `import tkinter as tk; r = tk.Tk(); help(r.quit);` and `import tkinter as tk; r = tk.Tk(); help(r.destroy);` to see the docstring of the methods. – Nae Feb 16 '18 at 17:21
  • 1
    @Nae It appears both questions should be marked as duplicates of [How do I close a tkinter window?](https://stackoverflow.com/q/110923/3357935) – Stevoisiak Feb 22 '18 at 14:24

1 Answers1

3

It is because quit causes mainloop to exit. With no event loop running, there's nothing left to keep the main window alive.

If you want to close a child window, call the destroy method.

self.close_button = tk.Button(..., command=self.top.destroy)
Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685