13

I am writing an application using Tkinter along with threading.

The problem I got is, after closing the main app, some thread is still running, and I need a way to check whether the root windows has been destroyed to avoid the TclError: can't invoke "wm" command.

All methods I know: wminfo_exists() and state() all return error once the root is destroyed.

martineau
  • 119,623
  • 25
  • 170
  • 301
bizi
  • 3,398
  • 2
  • 27
  • 28

2 Answers2

11

I will add my workaround for this, in case anyone came across the same issue. I was following the suggestion from here. I intercept the windows' closing event to set my flag that marks the root is already dead, and check for that flag when I need.

exitFlag = False

def thread_method():
    global root, exitFlag
    if not exitFlag:
        // execute the code relate to root

def on_quit():
    global exitFlag
    exitFlag = True
    root.destroy()

root.protocol("WM_DELETE_WINDOW", on_quit)
Community
  • 1
  • 1
bizi
  • 3,398
  • 2
  • 27
  • 28
3

If you are using something like this:

import Tkinter

root = Tkinter.Tk()
root.bind('<space>', lambda e: root.quit())  # quitting by pressing spacebar
root.mainloop()

and not: root.destroy() then the quit method will kill the Tcl interpreter not just breaks out from the mainloop and deletes all widgets. So once you called root.quit() you can be sure, that your root is completely dead!

All the other methods you suggested (like: wminfo_exists()) are only available when at least one valid Tk exists.


NOTE:

If you are using more than one mainloop, you should use the destroy method to make sure, that your main mainloop won't be killed -- but I don't think this is your case.

Peter Varo
  • 11,726
  • 7
  • 55
  • 77
  • 2
    Thanks for your answer. The problem I am having, is that after `root.quit()` I still have some threads running, and I need to let my thread knows that the `root` is already dead. Right now I have to settle with intercepting the quit method and set a global variable to let my thread know that the `root` is dead. I wonder if there would be any other solution. – bizi Nov 18 '13 at 23:07
  • 1
    `root.winfo_exists()` (without 'm')? anyway, why don't you catch that error with a try/except and when it happens you just kill your thread? – Peter Varo Nov 19 '13 at 01:16
  • I was following the [discussion about thread](http://stackoverflow.com/questions/323972/is-there-any-way-to-kill-a-thread-in-python) and they mention, it is bad practice to kill a thread during execution. That's why I hope to find a solution that let my program's execution end "peacefully". – bizi Nov 19 '13 at 17:27