拦截关闭窗口按钮(Tkinter窗口)引发Tcl错误
我有一个程序,它会在某个时候打开一个新窗口,这个窗口里有很多按钮和小工具,供用户选择和操作。这个窗口的定义如下:
def window(self,master):
def close(self):
# change some variables
self.destroy()
top = self.top = Toplevel()
# Several lines of buttons
top.lift()
top.protocol("WM_DELETE_WINDOW",close(self))
最开始我在窗口里放了一个关闭按钮,这样用户可以很方便地关闭窗口。但是我发现,如果用户直接点击窗口右上角的“X”按钮,这个关闭功能就不会被调用,这样后面会出现很多问题。我在这个网站上看到有人提到过“WM_DELETE_WINDOW”,我试着用了一下,但却遇到了一个奇怪的错误:
File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1630, in wm_protocol
'wm', 'protocol', self._w, name, command)
TclError: bad window path name ".33862072"
我猜可能是窗口的ID搞错了,所以无法捕捉到这个事件。我的问题是,这种情况是真的吗?如果是真的,我该怎么解决这个问题呢?
1 个回答
0
让我们来看看这行代码:
top.protocol("WM_DELETE_WINDOW",close(self))
这行代码的意思是“立刻调用函数 close(self)
,并把结果赋值给协议处理器。”你看出问题了吗?它是立刻调用 close
,很可能在 self
还没有完全构建好之前就调用了。你并不想让这个函数被“调用”,而是想传递一个对这个函数的“引用”。
把 close
改成 self
的一个方法(而不是一个嵌套的函数),然后把对 top.protocol
的调用改成这样(注意后面没有括号):
top.protocol("WM_DELETE_WINDOW", self.close)
如果你更喜欢保留嵌套函数,可以使用 lambda:
top.protocol("WM_DELETE_WINDOW", lambda window=self: close(window))