【问题标题】:Intercepting the close window button (Tkinter window) throws an Tcl error拦截关闭窗口按钮(Tkinter 窗口)会引发 Tcl 错误
【发布时间】:2014-06-05 11:41:27
【问题描述】:

我有一个程序,它在某些时候会打开一个新窗口(充满按钮和小玩意供用户选择和使用),其定义如下:

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 并且无法捕获该事件。因此,我的问题是,这是真的还是假的,其次我应该如何继续处理这个问题。

【问题讨论】:

  • 好吧top.protocol("WM_DELETE_WINDOW",self.close)
  • 我对@9​​87654324@并不完全熟悉,但如果它类似于bind,那么您可能实际上是在最后一行调用close,而不是将其注册为回调为WM_DELETE_WINDOW。注册需要参数的函数的典型解决方案是将它们包装在 lambda 中:top.protocol("WM_DELETE_WINDOW", lambda: close(self))
  • @Kevin 这完全让我忘记了,我现在觉得自己像个白痴:(

标签: python tkinter window


【解决方案1】:

让我们看看这行代码:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-29
    相关资源
    最近更新 更多