简体   繁体   中英

tkinter wait_window() raising tkinter.TclError: Bad window path name

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!

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM