Delrius Euphoria
Delrius Euphoria

Reputation: 15098

Understanding mainloop() better

My understanding of tk.mainloop() was that it would run and handle the events of window related to the first created Tcl interpreter and <widget>.mainloop() would handle the events of the window related to the interpreter linked with the widget. Then I came across this code:

from tkinter import *

root1 = Tk()
root2 = Tk()

root1.mainloop() # Shouldn't this just handle the events of the first window

According to my understanding I thought this code was supposed to handle just the events related to root1, but root2 also comes up and it is responsive too(which means that its events are also being processed..?). Do correct me if my understanding of how mainloop() works is wrong.

Thanks :D

Upvotes: 1

Views: 794

Answers (1)

Donal Fellows
Donal Fellows

Reputation: 137567

The mainloop() method runs the event processing loop on the current thread until all windows started in the thread have closed or the quit() method is called (which internally sets a flag that is checked by the core event loop runner). It blocks the thread, except that it does all the registered callbacks as necessary. The underlying machinery is not actually associated with any particular window, but rather with a thread. It's just that Tkinter prefers to not map things as free functions, despite that really being what they are.

You're pretty strongly recommended to not have the results of two calls to tkinter.Tk() active at once. It works, but the result can be quite confusing. It can get even more confusing if you do it from several threads at once (which is supposed to work — except on macOS for messy reasons — but the results tend to be mind-bending). (This does not apply to tkinter.Tcl(); that does work reasonably when done multiple times, and from multiple threads. The object it produces is thread-bound, but having many instances is sensible, and you can have those instances either in their own threads or together.)


What doing two calls to tkinter.Tk() like you've done does is create two separate underlying Tcl/Tk environments (the technical term is an “interpreter” even though that's got a bytecode compiler and so on) sharing a thread. This is sensible from a Tcl/Tk perspective due to the very different security model that Tcl uses, but it's almost total nonsense from the view of Python. The effects are describable small-scale operationally, but making broader sense of them is very difficult, and you're advised to not try.

Upvotes: 2

Related Questions