With default widgets, such as sliders, it is possible to observe the value or other traits so that any changes trigger a given function (see here):
w_slider = widgets.IntSlider()
w_output = widgets.Output()
def on_value_change(change_dict):
with w_output:
print(change_dict['new'])
w_slider.observe(on_value_change, names='value')
display(w_slider, w_output)
(I couldn’t find a comprehensive list of available observable traits for each widget type, but it is not relevant for my question I think)
Is it possible to define/trigger custom observables in subclassed widgets? I mean, without having to implement the pattern myself (i.e. having to write my own suscribe_observer
and notify_observer
methods to keep up with the list of subscribers and notifications). I thought of 2 options of how it might be done, but maybe there is another way.
# Define the component
#----------------------------------------------------------------#
class CustomComponent(widgets.VBox):
def __init__(self):
self._internal_value = None
# initialization of sub-components
# Option 1: trigger the observe event when making changes
def change_internal_value(self, newval):
self._trigger_event("internal_value", {'type': 'change'})
self._internal_value = newval
# Option 2: mark a property as an observable and ipywidgets takes care of triggering events
@widgets.mark_as_observable
@property
def internal_value(self):
return self._internal_value
# Instantiate and observe the component
#----------------------------------------------------------------#
custom_component = CustomComponent()
def dont_touch(change_dict):
print('Careful, you are changing the value!')
custom_component.observe(dont_touch, "internal_value")