I have a Python application with a Tkinter GUI. In the app, the user invokes a long-running background process (implemented as a Thread
from Python's threading
module). I'm having trouble killing the background thread if I quit the program before it's complete. My code works if I quit the application by closing the root window via the 'X' at its top corner, but not if I quit from the top-level menu bar (i.e. Python > Quit or Ctrl+Q). Since most applications use the latter, I'd really like to make that work.
Right now, I kill the background thread with code that looks like this:
class BackgroundCallFrame(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.background_call = BackgroundCall()
self.background_call.start()
class BackgroundCall(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self._stop_req = threading.Event()
def run(self):
for i in range(1,100000):
if self._stop_req.is_set():
return
else:
# do stuff
def stop(self):
self._stop_req.set();
def main():
def kill_all_threads():
if child.background_call is not None:
child.background_call.stop()
child.background_call.join()
root.destroy()
root = Tk()
root.wm_protocol ("WM_DELETE_WINDOW", kill_all_threads)
child = BackgroundCallFrame()
child.pack()
root.mainloop()
if __name__ == '__main__':
main()
How can I make this work if I quit the program without explicitly closing the root window first?
I believe my problem is that kill_all_threads()
is not called when I invoke Ctrl+Q, because any print statements I add to it never appear in the console.