0
votes

I have a script which has two tkinter.Tk() objects, two windows. One is hidden from the start (using .withdraw()), and each has a button which hides itself and shows the other (using .deiconify()). I use .mainloop() on the one shown in the beginning. Everything works, but when I close either window, the code after the mainloop() doesn't run, and the script doesn't end.

I suppose this is because one window is still open. If that is the case, how do I close it? Is it possible to have a check somewhere which closes a window if the other is closed?

If not, how do I fix this?

The essence of my code:

from tkinter import *

window1 = Tk()
window2 = Tk()
window2.withdraw()

def function1():
    window1.withdraw()
    window2.deiconify()

def function2():
    window2.withdraw()
    window1.deiconify()

button1 = Button(master=window1, text='1', command=function1)
button2 = Button(master=window2, text='2', command=function2)

button1.pack()
button2.pack()

window1.mainloop()
1
was answered quiet a few minutes ago. stackoverflow.com/a/63344280/13629335 - Atlas435
I'll read through that, and get back to you in 10-15 minutes. - Green05
It's rarely a good idea to use more than one instance of Tk. Is there a reason you're not using a Toplevel for the second window? - Bryan Oakley
I'm pretty new at tkinter, I don't know what Toplevel is. I'll read about it, perhaps it's the solution. By the way, why's it a bad idea to use multiple Tk? - Green05
because you are creating a new instance of Tk(), then everything in the first window will stay withtin that window only and cannot be used with the second window - Cool Cloud

1 Answers

1
votes

Compiling answers from comments:

  1. Use Toplevel instead of multiple Tk()s. That's the recommended practice, because it decreases such problems and is a much better choice in a lot of situations.

  2. Using a protocol handler, associate the closing of one window with the closing of both. One way to do this is the following code:

from _tkinter import TclError

def close_both():
    for x in (window1,window2):
        try:
            x.destroy()
        except TclError:
            pass
for x in (window1,window2):
    x.protocol("WM_DELETE_WINDOW", close_both)