简体   繁体   English

_tkinter.TclError: 坏 window 关闭时的路径名 window

[英]_tkinter.TclError: bad window path name when closing window

I've made a tk.Toplevel class to get a date from the user.我做了一个tk.Toplevel class 来从用户那里获取日期。 After the user clicked the date, the window is closing and the date should return to the mainprocess.用户点击日期后,window 正在关闭,日期应该返回到主进程。 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?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()

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.似乎 tkinter 在它被销毁后试图调用 kalender.dateentry。

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).这是因为当用户在弹出日历中选择了一个日期时,将执行 bind function self.close_window()并销毁顶层( DateEntry小部件也是如此)。 Then DateEntry widget closes the pop-up calendar which raises the exception.然后DateEntry小部件关闭引发异常的弹出日历。

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.close_window()的执行,以便在使用after()关闭弹出日历后执行它:

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

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我不是 100% 确定这一点,但似乎tkcalendar模块在通过DateEntry class 上的绑定强制销毁父小部件时遇到了一些麻烦。您可以尝试使用withdraw命令,它隐藏了 window 而不是摧毁它

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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