如何删除所有以前注册的小部件事件处理程序(已注册观察或 on_click)

How to remove all previous registered handlers for widgets events (registered with observe or on_click)

我已经创建并注册了一个处理程序。

# Example code
selectWidgetName.observe(myFunction, 'value')

然后我更新了函数的代码,想用同样的命令重新注册。

添加一个与第一个并行的处理程序,而不是覆盖第一个。

如何删除所有现有的处理程序以便应用一个新的且唯一的处理程序?

对于按钮:

# Remove existing click handler
buttonWidgetName._click_handlers.callbacks = []

# Add our handler
buttonWidgetName.on_click(newFunction)

对于使用观察的小部件:

# Remove existing handler 
# not sure if this
selectWidgetName.unobserve(None)
# or this
selectWidgetName.unobserve(oldFunction)

# Add our handler
selectWidgetName.observe(newFunction, 'value')

感谢 NimSed 第二个。

但是,如果您尝试删除仍然不存在的处理程序,您会得到

/usr/local/lib/python3.7/dist-packages/traitlets/traitlets.py in _remove_notifiers(self, handler, name, type)
   1284                 del self._trait_notifiers[name][type]
   1285             else:
-> 1286                 self._trait_notifiers[name][type].remove(handler)
   1287         except KeyError:
   1288             pass

ValueError: list.remove(x): x not in list

所以我们需要一种方法来了解附加到小部件的 existing handlers,如果存在,将其删除。

要知道所有的handler都看

widget_name._trait_notifiers

示例输出:

{'comm': {'change': [<traitlets.traitlets.ObserveHandler at 0x7efe05c4e9d0>]},
 'index': {'change': [<traitlets.traitlets.ObserveHandler at 0x7efe05bc4090>]},
 'label': {'change': [<traitlets.traitlets.ObserveHandler at 0x7efe05bc4290>]},
 'options': {'change': [<traitlets.traitlets.ObserveHandler at 0x7efe05c3ef50>]},
 'value': {'change': [<traitlets.traitlets.ObserveHandler at 0x7efe05bc4190>,
   <function __main__.funct_f1>,
   <function __main__.funct_f2>]}}

所以把它们放在一起

# Check if present
if funct_f1 in widget_name._trait_notifiers['value']['change']:
  # Remove
  wordSelector.unobserve(handler=funct_f1, names='value', type='change')
  print("Removed handler")
# Attach
widget_name.observe(handler=funct_f1, names='value', type='change')
print("Attached handler")