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.