Python — Tkinter rendering on the mainloop

Donovan Walker
2 min readFeb 15, 2022

Let me be clear.

  1. I’m mildly intoxicated at the moment.
  2. I thought of this article when I was sober
  3. Python is great! I really don’t like TKinter. (On a scale from Unreal Engine 5 all the way down to a monochrome terminal it falls somewhere below OhMyZsh)

Goal: Fix your “RuntimeError: main thread is not in main loop” issues.

Ok, so maybe I’m a little more than mildly intoxicated. Whatever. This solution works. Every Time.

I’ll outline the concept, and if I’m coherent enough I’ll give you a code-example.

The “mainloop” issue (approximation, I apologize. See above intoxication comments) is that TKinter attempts to inspect the current thread and make sure that it’s the thread that was called when you did something like tk.mainloop()

So, the question that leads to the correct solution is “How do I render something wherever and whenever I want while making sure it’s in the mainloop? What’s the magic sauce?”

The answer is both simple and sh!tty. In either your root file, or your main UI rendering class (one that probably extends Frame or the like) you create a queue and implement an .after call in the constructor that consumes all the items in that queue before sleeping, and calling itself again Then, you make all the little individual render calls you do in your application into lambda functions that get added to the queue I mentioned above.

That’s pretty-much it. You can pass the queue to all your child UI elements, or use whatever event-buss you’re triggering to also put events into the queue. The possibilities are limitless there.

I really wish medium supported .md formatting. I’d be all-over ``` code blocks right now.

Sigh.

I don’t wanna without markdown but —

This could go at the end of your main constructor:
self.after(250, self._process_mainloop_events_queue)

and then you could do a try-catch block processing an instance of queue. At the end, make the same after call.

I’m sure you get the idea. And please, if you want a real example or just want the solution leave a comment. The code-type formatting here sucks.

I’m still … in der bier.

--

--