0

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()
Green05
  • 319
  • 1
  • 8
  • was answered quiet a few minutes ago. https://stackoverflow.com/a/63344280/13629335 – Thingamabobs Aug 10 '20 at 17:17
  • I'll read through that, and get back to you in 10-15 minutes. – Green05 Aug 10 '20 at 17:22
  • 1
    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 Aug 10 '20 at 17:23
  • 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 Aug 10 '20 at 17:25
  • 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 – Delrius Euphoria Aug 10 '20 at 17:43
  • Okay @CoolCloud. Just curious, if i use a protocol handler this way: `window1.protocol("WM_DELETE_WINDOW", close_both)` where close_both destroys both windows (perhaps using try/except), would that work or create any additional problems? – Green05 Aug 10 '20 at 17:49
  • did you try it out? did it work? since the `protocol` is for window1, it might work but im not sure – Delrius Euphoria Aug 10 '20 at 17:50
  • @CoolCloud Yup, works. I'll go for Toplevel from now on, though. – Green05 Aug 10 '20 at 17:54
  • Yes, its a good practice – Delrius Euphoria Aug 10 '20 at 17:55

1 Answers1

1

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)
Green05
  • 319
  • 1
  • 8