使用tkinter无法解除绑定函数

5
我正在使用Python 3.5中的Tkinter,并遇到一个奇怪的问题。
我使用 tkinterbook关于事件和绑定来编写这个简单的示例:
from tkinter import *

root = Tk()

frame = Frame(root, width=100, height=100)

def callback(event):
    print("clicked at", event.x, event.y)
    # frame.unbind("<Button-1>", callback)

frame.bind("<Button-1>", callback)
frame.pack()

root.mainloop()

它可以正常工作,但是如果我尝试解除回调绑定(只需取消注释该行),它会出现以下错误:

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Users\Delgan\AppData\Local\Programs\Python\Python35\lib\tkinter\__init__.py", line 1549, in __call__
    return self.func(*args)
  File "C:\Users\Delgan\Desktop\Test\test.py", line 9, in callback
    frame.unbind("<Button-1>", callback)
  File "C:\Users\Delgan\AppData\Local\Programs\Python\Python35\lib\tkinter\__init__.py", line 1105, in unbind
    self.deletecommand(funcid)
  File "C:\Users\Delgan\AppData\Local\Programs\Python\Python35\lib\tkinter\__init__.py", line 441, in deletecommand
    self.tk.deletecommand(name)
TypeError: deletecommand() argument must be str, not function

这不是很清楚,我不确定这是tkinter中的一个错误还是我做错了什么。

frame.unbind("<Button-1>")可以正常工作,但我想删除这个特定的回调函数而不是全局删除。


我无法重现你的问题。 - Billal Begueradj
1个回答

8

unbind方法的第二个参数是一个“funcid”,而不是一个函数。使用help(root.unbind)可以查看如下信息:

unbind(sequence, funcid=None)方法是tkinter.Tk实例的一种方法。对于事件SEQUENCE,解除该小部件上标识为FUNCID的函数的绑定。

许多tk函数返回可以作为其他函数参数的tk对象ID之类的内容,其中bind就是其中之一。

>>> i = root.bind('<Button-1>', int)
>>> i
'1733092354312int'
>>> root.unbind('<Button-1>', i)  # Specific binding removed.
< p > 在 help(root.bind) 的输出中有这样一句话: "Bind 会返回一个标识符,允许使用 unbind 删除绑定的函数而不会导致内存泄漏。" < /p >

哦,这很有道理,谢谢你,我没有想到这一点。也许是Python的最近一个版本改变了API,这可以解释为什么我找到的例子使用函数本身而不是funcid,并且为什么@BillalBEGUERADJ没有相同的问题。 - Delgan
2
我知道现在有点晚了,但对于所有未来遇到这个问题的人:如果你只想解除绑定一个函数,可以执行以下操作:root.unbind("", <id>),因为上面的示例将删除给定序列('<Button-1>')的所有绑定,而不管函数的ID。 - Nummer_42O
有些人认为可以通过在根部件上调用unbind()而不是在小部件上调用来解除绑定在小部件(而不是根部件)上的多个处理程序中的特定处理程序。(请参见另一个问题上我的答案的评论。)那么提到这是错误的吗? - relent95
@Nummer_420,那会导致未定义的行为。请参阅实现获取详细信息。 - relent95

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接