Widget Events

Special events


In [1]:
from __future__ import print_function

The Button is not used to represent a data type. Instead the button widget is used to handle mouse clicks. The on_click method of the Button can be used to register function to be called when the button is clicked. The doc string of the on_click can be seen below.


In [2]:
from IPython.html import widgets
print(widgets.Button.on_click.__doc__)


Register a callback to execute when the button is clicked.

        The callback will be called with one argument,
        the clicked button widget instance.

        Parameters
        ----------
        remove : bool (optional)
            Set to true to remove the callback from the list of callbacks.
:0: FutureWarning: IPython widgets are experimental and may change in the future.

Example

Since button clicks are stateless, they are transmitted from the front-end to the back-end using custom messages. By using the on_click method, a button that prints a message when it has been clicked is shown below.


In [3]:
from IPython.display import display
button = widgets.Button(description="Click Me!")
display(button)

def on_button_clicked(b):
    print("Button clicked.")

button.on_click(on_button_clicked)

on_sumbit

The Text also has a special on_submit event. The on_submit event fires when the user hits return.


In [4]:
text = widgets.Text()
display(text)

def handle_submit(sender):
    print(text.value)

text.on_submit(handle_submit)


Hi

Traitlet events

Widget properties are IPython traitlets and traitlets are eventful. To handle changes, the on_trait_change method of the widget can be used to register a callback. The doc string for on_trait_change can be seen below.


In [5]:
print(widgets.Widget.on_trait_change.__doc__)


Setup a handler to be called when a trait changes.

        This is used to setup dynamic notifications of trait changes.

        Static handlers can be created by creating methods on a HasTraits
        subclass with the naming convention '_[traitname]_changed'.  Thus,
        to create static handler for the trait 'a', create the method
        _a_changed(self, name, old, new) (fewer arguments can be used, see
        below).

        Parameters
        ----------
        handler : callable
            A callable that is called when a trait changes.  Its
            signature can be handler(), handler(name), handler(name, new)
            or handler(name, old, new).
        name : list, str, None
            If None, the handler will apply to all traits.  If a list
            of str, handler will apply to all names in the list.  If a
            str, the handler will apply just to that name.
        remove : bool
            If False (the default), then install the handler.  If True
            then unintall it.
        

Signatures

Mentioned in the doc string, the callback registered can have 4 possible signatures:

  • callback()
  • callback(trait_name)
  • callback(trait_name, new_value)
  • callback(trait_name, old_value, new_value)

Using this method, an example of how to output an IntSlider's value as it is changed can be seen below.


In [6]:
int_range = widgets.IntSlider()
display(int_range)

def on_value_change(name, value):
    print(value)

int_range.on_trait_change(on_value_change, 'value')


3
6
11
16
22
26
30
33
35
37
38
40
41
42
43
44
45
44
43
40
38
36
34
32
31
30
29
28
27
26
25
24
23
22

Linking Widgets

Often, you may want to simply link widget attributes together. Synchronization of attributes can be done in a simpler way than by using bare traitlets events.

The first method is to use the link and directional_link functions from the traitlets module.

Linking traitlets attributes from the server side


In [7]:
from IPython.utils import traitlets

In [9]:
caption = widgets.Latex(value = 'The values of slider1, slider2 and slider3 are synchronized')
sliders1, slider2, slider3 = widgets.IntSlider(description='Slider 1'),\
                             widgets.IntSlider(description='Slider 2'),\
                             widgets.IntSlider(description='Slider 3')
l = traitlets.link((sliders1, 'value'), (slider2, 'value'), (slider3, 'value'))
display(caption, sliders1, slider2, slider3)

In [11]:
caption = widgets.Latex(value = 'Changes in source values are reflected in target1 and target2')
source, target1, target2 = widgets.IntSlider(description='Source'),\
                           widgets.IntSlider(description='Target 1'),\
                           widgets.IntSlider(description='Target 2')
traitlets.dlink((source, 'value'), (target1, 'value'), (target2, 'value'))
display(caption, source, target1, target2)

Function traitlets.link returns a Link object. The link can be broken by calling the unlink method.


In [12]:
# l.unlink()

Linking widgets attributes from the client side

When synchronizing traitlets attributes, you may experience a lag because of the latency dues to the rountrip to the server side. You can also directly link widgets attributes, either in a unidirectional or a bidirectional fashion using the link widgets.


In [13]:
caption = widgets.Latex(value = 'The values of range1, range2 and range3 are synchronized')
range1, range2, range3 = widgets.IntSlider(description='Range 1'),\
                         widgets.IntSlider(description='Range 2'),\
                         widgets.IntSlider(description='Range 3')
l = widgets.jslink((range1, 'value'), (range2, 'value'), (range3, 'value'))
display(caption, range1, range2, range3)

In [ ]:
caption = widgets.Latex(value = 'Changes in source_range values are reflected in target_range1 and target_range2')
source_range, target_range1, target_range2 = widgets.IntSlider(description='Source range'),\
                                             widgets.IntSlider(description='Target range 1'),\
                                             widgets.IntSlider(description='Target range 2')
widgets.jsdlink((source_range, 'value'), (target_range1, 'value'), (target_range2, 'value'))
display(caption, source_range, target_range1, target_range2)

Function widgets.jslink returns a Link widget. The link can be broken by calling the unlink method.


In [ ]:
# l.unlink()