Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are multiple instances of Tk discouraged?

Consider below example:

import tkinter as tk

root = tk.Tk()
root.title("root")

other_window = tk.Tk()
other_window.title("other_window")

root.mainloop()

and also see below example that creates instances of Tk back-to-back instead of at once, so there's exactly one instance of Tk at any given time:

import tkinter as tk

def create_window(window_to_be_closed=None):
    if window_to_be_closed:
        window_to_be_closed.destroy()
    window = tk.Tk()
    tk.Button(window, text="Quit", command=lambda arg=window : create_window(arg)).pack()
    window.mainloop()

create_window()
  • Why is it considered bad to have multiple instances of Tk?
  • Is the second snippet considered a bit better, or does it suffer from the same conditions the first code does?
like image 977
Nae Avatar asked Dec 31 '17 20:12

Nae


1 Answers

I disagree with the tkinter community discouraging the use of multiple tk.Tk windows. You can have multiple tk.Tk windows. Using multiple instances of tk.Tk is the only way to create windows that are truly independent of each other. The most only mistake people do when creating multiple tk.Tk windows is that they forget to pass in master=... when creating PhotoImages/StringVars/IntVars/...

For example look at this code:

import tkinter as tk

root = tk.Tk()
root2 = tk.Tk()

variable = tk.StringVar() # Add `master=root2` to fix the problem
entry = tk.Entry(root2, textvariable=variable)
entry.bind("<Return>", lambda e: print(repr(variable.get())))
entry.pack()

root.mainloop()

The code above doesn't work. If you add master=root2 to the tk.StringVar(), then it will work perfectly fine. This is because tkinter stores the first instance of tk.Tk() in tk._default_root. Then if you don't pass in master=..., it will assume that you wanted the window in tk._default_root.


Another thing people get wrong is how many times should .mainloop() be called. It handles events from all tk.Tk windows that are alive so you only need one .mainloop().

For folks who disagree, I'd be interested in an example of where an actual problem is caused by the multiple tk.Tk windows.

like image 74
TheLizzard Avatar answered Oct 07 '22 00:10

TheLizzard