RuntimeError: main thread is not in main loop

You’re running your main GUI loop in a thread besides the main thread. You cannot do this.

The docs mention offhandedly in a few places that Tkinter is not quite thread safe, but as far as I know, never quite come out and say that you can only talk to Tk from the main thread. The reason is that the truth is somewhat complicated. Tkinter itself is thread-safe, but it’s hard to use in a multithreaded way. The closest to official documentation on this seems to be this page:

Q. Is there an alternative to Tkinter that is thread safe?

Tkinter?

Just run all UI code in the main thread, and let the writers write to a Queue object…

(The sample code given isn’t great, but it’s enough to figure out what they’re suggesting and do things properly.)

There actually is a thread-safe alternative to Tkinter, mtTkinter. And its docs actually explain the situation pretty well:

Although Tkinter is technically thread-safe (assuming Tk is built with –enable-threads), practically speaking there are still problems when used in multithreaded Python applications. The problems stem from the fact that the _tkinter module attempts to gain control of the main thread via a polling technique when processing calls from other threads.

I believe this is exactly what you’re seeing: your Tkinter code in Thread-1 is trying to peek into the main thread to find the main loop, and it’s not there.

So, here are some options:

  • Do what the Tkinter docs recommend and use TkInter from the main thread. Possibly by moving your current main thread code into a worker thread.
  • If you’re using some other library that wants to take over the main thread (e.g., twisted), it may have a way to integrate with Tkinter, in which case you should use that.
  • Use mkTkinter to solve the problem.

Also, while I didn’t find any exact duplicates of this question, there are a number of related questions on SO. See this question, this answer, and many more for more information.

Leave a Comment