RuntimeError: main thread is not in main loop RuntimeError: main thread is not in main loop tkinter tkinter

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.


I know this is late, but I set my thread to a Daemon, and no exception was raised:

t = threading.Thread(target=your_func)t.setDaemon(True)t.start()


I found a way to solve it.it might look like a joke but you just should add

plt.switch_backend('agg')