0

I've created a tkinter app designed to let users create and take quizzes locally. Unfortunately, if a user closes the window by hitting the 'x' in the corner instead of hitting the "quit" button on the main menu, the window is destroyed but the process remains in the background. It isn't a huge deal as it stops using any CPU and only holds on to about 40mb of memory per instance, but this just seems pretty sloppy for an app that I'd like to deploy.

I have no idea what specifically is refusing to exit when the window is closed, and as it could be coming from almost anywhere in my 1700 lines of code, I'm instead looking for some more general tips for identifying what's still running or for killing any remaining processes when the window is closed. I'm happy to provide my code if anyone thinks it would help, though I reiterate that it's quite long given that I can't identify the source of the particular problem.

22Fonzie
  • 3
  • 3
  • What exactly does your "quit" button do? Are you doing anything specific in response to the X being clicked - this would be in the form `window.protocol("WM_DELETE_WINDOW, ...)`? – jasonharper Apr 24 '22 at 22:26
  • Please clarify your specific problem or provide additional details to highlight exactly what you need. As it's currently written, it's hard to tell exactly what you're asking. – Community Apr 24 '22 at 22:54
  • @jasonharper Exit button currently just calls the sys.exit() method. All I know is that this doesn't leave any background processes running, while force-closing the window does. – 22Fonzie Apr 25 '22 at 16:39

3 Answers3

0

You can use state() from Tk to check if the window is open or not. When the window is open it should return 'normal' and if the window isn't open it will return something else.

What I would do is add something that checks the state of the window and exit the app when it's closed.

while app_is_running:
    if root.state() != 'normal':
        sys.exit(0)
0

I had had a similar problem in my Tkinter application. I learned from this post that I could set a callback for window deletion like this:

def closing_cbk():
    # Shutdown procedure
    root.quit()
    root.destroy()
...
root.protocol("WM_DELETE_WINDOW", closing_cbk)

And you can replace the contents of the closing_cbk() with "sys.exit()" or something else that makes more sense for your particular application.

Wilson
  • 399
  • 2
  • 10
0

I believe this is the exact solution to your question. I read this thread before finding the solution, so I thought it would be good to contribute. The quit method and destroy methods did not work for me. Instead, I obtained the process ID (PID) for the main program and any subprocesses generated. I have included a snipping of how I implemented this so that all processes closed when I pressed the exit window button in Linux. Its a class called 'Moisure' using custom tkinter where process objects generated called P and L (for my plotter and logger processes) called inside were obtained to kill. Your program should finish the if statement upon closing. The 'try' statement is in case I never started those processes. This has not been tested on any other operating, but it should work on windows as well but Ive read packaging as an exe has fixed this.

import os, signal

if __name__ == "__main__":
    app = Moisture()
    app.mainloop()
    try:
        app.P.kill()
    except:
        pass
    try:
        app.L.kill()
    except:
        pass
    PID = os.getpid()
    os.kill(PID, signal.SIGKILL) 

Also, I haven't seen your code but I suggest using try and except methods in various ways to ensure that your program doesn't close prematurely and leave any subprocesses running in the background if you're running any. Hopefully it helps you and anyone else too!!!