Ответ, предоставленный Брайаном, в целом работает хорошо, но, как подчеркнул Аркра, он может и не быть. Если у вас возникла проблема с невозможностью правильно отсоединить сложенный обратный вызов, измените официальный источник - если он все тот же! - может быть решением.
Вот мои 2 цента для тех, кто все еще сталкивается с проблемой: пожалуйста, переопределите метод unbind (), НЕ РЕДАКТИРУЙТЕ ЕГО ПРЯМО.
Таким образом, фактически вам не нужно вручную изменять официальный исходный код на вашей рабочей станции (таким образом, нарушая управление пакетами, или повторно представляя проблему при следующем обновлении пакета, или создавая ту же проблему на другом клиенте). ..):
import tkinter as tk
class PatchedCanvas(tk.Canvas):
def unbind(self, sequence, funcid=None):
'''
See:
/5522619/udalenie-i-izmenenie-privyazki-sobytiya-tkinter
deleting-and-changing-a-tkinter-event-binding-in-python
'''
if not funcid:
self.tk.call('bind', self._w, sequence, '')
return
func_callbacks = self.tk.call(
'bind', self._w, sequence, None).split('\n')
new_callbacks = [
l for l in func_callbacks if l[6:6 + len(funcid)] != funcid]
self.tk.call('bind', self._w, sequence, '\n'.join(new_callbacks))
self.deletecommand(funcid)
Затем, вместо создания экземпляра вашего неисправного виджета (в моем примере я использую Canvas), как это
myCanvas = tk.Canvas(...)
вы просто создадите его экземпляр из своей исправленной версии, которая будет нуждаться в обновлении, если и только если официальный источник будет обновлен и исправлен:
myCanvas = PatchedCanvas(...)
В настоящее время метод unbind определен в классе Misc, из которого его наследует BaseWidget, а затем, соответственно, Widget, TopLevel, Button, ...