_tkinter.关闭窗口时,错误的窗口路径名



我创建了一个tk.Toplevel类来获取用户的日期。用户单击日期后,窗口将关闭,日期将返回到主进程。当tk.Toplevel关闭时,我得到了日期,但也有一个错误:_tkinter.TclError: bad window path name ".!kalender.!dateentry.!toplevel"我做错了什么?

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()

我得到了以下错误:

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

似乎,那个小精灵试图调用日历。销毁后的日期条目。

这是因为当用户在弹出式日历中选择了一个日期时,绑定函数self.close_window()将被执行并且顶层被销毁(DateEntry小部件也是如此)。然后DateEntry小部件关闭引发异常的弹出日历。

要解决这个问题,您可以将self.close_window()的执行延迟一点,以便在使用after():

关闭弹出式日历后执行它。
self.cal.bind("<<DateEntrySelected>>", lambda e: self.after(10, self.close_window, None))

我不是100%确定这一点,但似乎tkcalendar模块有一些麻烦,通过绑定在DateEntry类上强制销毁父小部件。您可以尝试使用withdraw命令,它隐藏窗口而不是破坏它

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

最新更新