Tkinker window not responding when clicked on the "Exit"

ghz 14hours ago ⋅ 5 views

I created a GUI using Python, Tkinter. Everything seems to be fine. I have added several options to my Menu tab. In the File section I have added a feature to exit the GUI by clickinh onto the Exit button(not the button though, but a menu option). Here is the code that I have written.

from tkinter import *
from tkinter import filedialog, RIGHT

class Filedialog:
    def directory(self):
        content = filedialog.askdirectory()
        return content



class Main(Frame):


    def __init__(self):
        self.opening_times = 0
        self.current_image = 0
        self.images = []
        self.root = Tk()
        self.root.title("Y")
        self.root.configure(bg='pale turquoise')
        self.root.geometry("800x800")
        self.frame = Frame(self.root)
        self.frame.pack(side=RIGHT)
        self.frame = Frame.__init__(self, self.root)
        self.widgets()
        self.root.mainloop()


    def widgets(self):

        self.menu = Menu(self.root)
        self.root.config(menu=self.menu)
        self.filemenu = Menu(self.menu, tearoff=False)
        self.menu.add_cascade(label="File", menu=self.filemenu)
        self.filemenu.add_separator()
        self.filemenu.add_command(label="Save")
        self.filemenu.add_separator()
        self.filemenu.add_command(label="Exit", command=self.onExit)
        #self.editmenu = Menu(self.menu, tearoff=0)
        #self.menu.add_cascade(label='Edit', menu=self.editmenu)
        #self.editmenu.add_command(label="Undo")
        #self.editmenu.add_command(label="Redo")


    def onExit(self):
        self.root.quit()



if __name__ == "__main__":
    Main()

I have almost succeeded. But the problem arises when I click on the exit. The function does what it has to. But the GUI window was not closing, also it freezes there. There was no response at all until I force the window to close externally.

I also tried doing:

self.quit()

/

self.exit()

But the response is the same as the GUI freezes and not letting me do any other activities. I had to close complete program to get the access again.

I am not getting the error at least, to know what is wrong.

Please help me find out what is wrong/solve this problem.

Answer

It looks like you are running into an issue where the GUI does not close as expected when you click the "Exit" option in the menu. The issue arises because you are calling self.root.quit() within the onExit method, but this is not always sufficient to close the Tkinter window properly in some situations.

Here's why this might be happening and how you can fix it:

Understanding quit() vs destroy()

In Tkinter, there are two main methods to handle the application exit:

  1. quit(): This method stops the Tkinter main loop but does not destroy the window. It will prevent the event loop from running, but the window itself remains open until you explicitly destroy it.
  2. destroy(): This method both stops the Tkinter main loop and closes the window.

The Solution

In your case, you should call the destroy() method on the root window (self.root) to completely exit the application and close the window.

Here is the corrected code:

from tkinter import *
from tkinter import filedialog, RIGHT

class Filedialog:
    def directory(self):
        content = filedialog.askdirectory()
        return content

class Main(Frame):

    def __init__(self):
        self.opening_times = 0
        self.current_image = 0
        self.images = []
        self.root = Tk()
        self.root.title("Y")
        self.root.configure(bg='pale turquoise')
        self.root.geometry("800x800")
        self.frame = Frame(self.root)
        self.frame.pack(side=RIGHT)
        self.frame = Frame.__init__(self, self.root)
        self.widgets()
        self.root.mainloop()

    def widgets(self):
        self.menu = Menu(self.root)
        self.root.config(menu=self.menu)
        self.filemenu = Menu(self.menu, tearoff=False)
        self.menu.add_cascade(label="File", menu=self.filemenu)
        self.filemenu.add_separator()
        self.filemenu.add_command(label="Save")
        self.filemenu.add_separator()
        self.filemenu.add_command(label="Exit", command=self.onExit)

    def onExit(self):
        # Use destroy instead of quit
        self.root.destroy()

if __name__ == "__main__":
    Main()

Key Change:

In the onExit method, I replaced self.root.quit() with self.root.destroy(). This ensures that the Tkinter application is properly destroyed and closed when the "Exit" menu option is clicked.

Why This Works:

  • quit(): While quit() stops the event loop, it does not actually close the window or free up resources, so the window remains visible but unresponsive.
  • destroy(): This method stops the event loop and completely destroys the window, effectively closing it.

By using self.root.destroy(), the application closes gracefully without freezing or requiring forceful termination.

Conclusion:

Whenever you want to close a Tkinter application, always use destroy() instead of quit() to ensure that both the main loop and the window are closed properly.