拦截关闭窗口按钮(Tkinter 窗口)抛出 Tcl 错误 [英] Intercepting the close window button (Tkinter window) throws an Tcl error
问题描述
我有一个程序,它会在某个时候打开一个新窗口(充满按钮和 Gizmo 供用户选择和使用),其定义如下:
I have a program that at some point opens a new window (filled with buttons and gizmo's for the user to select and play around with) that is defined as follows:
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"建议,但它给了我一个相当奇怪的错误:
I initially had a close button there that would wrap everything up nicely but I noticed that if the user used the standard 'X' in the corner of the window, this function obviously would not be called and that would give a lot of problems later on. I found out about the 'WM_DELETE_WINDOW' suggestion from some other questions on this website but it gives me a rather strange error:
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 并且无法捕获该事件.因此,我的问题是,这是真的还是假的,其次我应该如何继续处理这个问题.
I assume that it somehow has gotten the wrong window ID and is unable to catch the event. My question is thus, is that true or not and secondly how should I continue to deal with this issue.
推荐答案
让我们看看这行代码:
top.protocol("WM_DELETE_WINDOW",close(self))
这行代码是说立即调用函数close(self)
,并将结果分配给协议处理程序.看到问题了吗?它立即调用了close
,可能在 self
完全构造之前.您不希望该函数被调用,您希望将引用传递给功能.
This line of code is saying "immediately call the function close(self)
, and assign the result to the protocol handler. See the problem? It's immediately calling close
, likely before self
has been fully constructed. You don't want the function to be called, you want to pass in a reference to the function.
使 close
成为 self
的方法(而不是嵌入函数)并将对 top.protocol
的调用更改为如下所示(注意缺少尾随括号):
Make close
be a method of self
(rather than an embedded function) and change the call to top.protocol
to look like this (note the lack of trailing parenthesis):
top.protocol("WM_DELETE_WINDOW", self.close)
如果您更喜欢保留嵌套函数,可以使用 lambda:
If you prefer to keep the nested function, you can use lambda:
top.protocol("WM_DELETE_WINDOW", lambda window=self: close(window))
这篇关于拦截关闭窗口按钮(Tkinter 窗口)抛出 Tcl 错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!