tkinter wait_window() raising tkinter.TclError: Bad window path name
Question: I've been messing around with python's tkinter, and wrote the following code
for dialog practice:

    
    
    import tkinter as tk
    
    class Dialog(tk.Toplevel):
        def __init__(self, parent, title=None):
            tk.Toplevel.__init__(self, parent)
            self.transient(parent)
            if title: self.title(title)
            self.parent = parent
            self.result = None
            body = tk.Frame(self)
            self.e = tk.Entry(body)
            self.e.pack()
            self.initial_focus = self.e
            body.pack(padx=5, pady=5)
            self.buttonbox()
            self.grab_set()
            if not self.initial_focus: self.initial_focus = self
            self.protocol("WM_DELETE_WINDOW", self.cancel)
            self.geometry("+%d+%d"%(parent.winfo_rootx()+50, parent.winfo_rooty()+50))
            self.initial_focus.focus_set()
            self.wait_window(self)
        def buttonbox(self):
            box = tk.Frame(self)
            w = tk.Button(box, text="OK", width=10, command=self.ok, default=tk.ACTIVE)
            w.pack(side=tk.LEFT, padx=5, pady=5)
            w = tk.Button(box, text="Cancel", width=10, command=self.cancel)
            w.pack(side=tk.LEFT, padx=5, pady=5)
            self.bind("<Return>", self.ok)
            self.bind("<Escape>", self.cancel)
            box.pack()
        def ok(self, event=None):
            if not self.validate():
                self.initial_focus.focus_set()
                return
            self.withdraw()
            self.update_idletasks()
            self.apply()
            self.cancel()
        def cancel(self, event=None):
            self.parent.focus_set()
            self.destroy()
        def validate(self):
            if self.e.get(): return True
            else: return False
        def apply(self):
            value = self.e.get()
            self.parent.l.config(text=value)
    
    class App(tk.Tk):
        def __init__(self):
            tk.Tk.__init__(self)
            self.l = tk.Label(self, text="Hello!")
            self.b = tk.Button(self, text="Hello?", command=self.dialog, default=tk.ACTIVE)
            self.l.pack()
            self.b.pack()
        def dialog(self):
            self.dialogbox = Dialog(self)
            self.dialogbox.wait_window()
    
    app = App()
    app.mainloop()
    

So Dialog is a dialog box opened by App, and it's used to alter label's text,
etc. while it seems to run without much problem, the console shows following
error:

    
    
    Exception in Tkinter callback
    Traceback (most recent call last):
      File "C:\Users\Administrator\AppData\Local\Programs\Python\Python35-32\lib\tkinter\__init__.py", line 1549, in __call__
        return self.func(*args)
      File "C:\Users\Administrator\Documents\JW\Python 3.5\guiPractice.py", line 58, in dialog
        self.dialogbox.wait_window()
      File "C:\Users\Administrator\AppData\Local\Programs\Python\Python35-32\lib\tkinter\__init__.py", line 490, in wait_window
        self.tk.call('tkwait', 'window', window._w)
    _tkinter.TclError: bad window path name ".9605808"
    

From what I've found, it's raised because I'm trying to deal with a destroyed
object(self.dialogbox?), but I can't see why exactly this error is raised in
this case.

Please Help!


Answer: It is because the dialog itself is calling `wait_window` on itself, and then
after it is destroyed the main program is also calling `wait_window`. The
second call can't happen until after the first exits, and the first can't exit
until the window is destroyed.

