Home > Software design >  _tkinter.TclError: bad window path name when closing window
_tkinter.TclError: bad window path name when closing window

Time:11-17

I've made a tk.Toplevel class to get a date from the user. After the user clicked the date, the window is closing and the date should return to the mainprocess. When the tk.Toplevel is closed I've got the date, but also an error: \_tkinter.TclError: bad window path name ".!kalender.!dateentry.!toplevel" What did I do wrong?

class Kalender(tk.Toplevel):
    def __init__(self, parent, date=''):
        Toplevel.__init__(self, parent)

        # Fenster mittig zentrieren
        x = (self.winfo_screenwidth() // 2) - (100 // 2)
        y = (self.winfo_screenheight() // 2) - (50 // 2)
        self.grab_set()
        self.geometry('{}x{} {} {}'.format(180, 90, x, y))
        self.attributes('-toolwindow', True)
        self.title('Datum auswählen')
        self.resizable(width=False, height=False) 

        self.date = None
        self.sel = StringVar()
        self.cal = DateEntry(self, font="Arial 14", selectmode='day', locale='de_DE', date_pattern="dd.mm.y ",
                             textvariable=self.sel)
        self.cal.bind("<<DateEntrySelected>>", self.close_window)
        self.cal.set_date(date)
        self.cal.grid(row=0, column=0, padx=10, pady=10, sticky=W E)
        self.focus_set()


    def close_window(self, e):
        self.date = self.cal.get()
        self.destroy()

    def show(self):
        self.deiconify()
        self.wm_protocol("WM_DELETE_WINDOW", self.close_window)
        self.wait_window()
        return self.date
cal = Kalender(main_window, d).show()

I've got the following error:

Exception in Tkinter callback
Traceback (most recent call last):
  File "B:\Python 310\lib\tkinter\__init__.py", line 1921, in __call__
    return self.func(*args)
  File "B:\Python 310\lib\site-packages\tkcalendar\dateentry.py", line 301, in _select
    self._top_cal.withdraw()
  File "B:\Python 310\lib\tkinter\__init__.py", line 2269, in wm_withdraw
    return self.tk.call('wm', 'withdraw', self._w)
_tkinter.TclError: bad window path name ".!kalender.!dateentry.!toplevel"

It seems, that tkinter tries to call the kalender.dateentry after it has been destroyed.

CodePudding user response:

I am not 100% sure about this, but it seems the that the tkcalendar module has some trouble forcing a destroy on the parent widget through a bind on the DateEntry class. You can try using the withdraw command instead, which hides the window rather than destroying it

def close_window(self, e):
    self.date = self.cal.get()
    self.withdraw()

CodePudding user response:

It is because when the user has selected a date in the pop-up calendar, the bind function self.close_window() will be executed and the toplevel is destroyed (so is the DateEntry widget). Then DateEntry widget closes the pop-up calendar which raises the exception.

To fix this, you can delay the execution of self.close_window() a bit so that it is executed after the pop-up calendar is closed using after():

self.cal.bind("<<DateEntrySelected>>", lambda e: self.after(10, self.close_window, None))
  • Related