Widget events#

Special events#

[1]:
from __future__ import print_function

Button cannot be used to represent a data type, but only for on_click. With the print function the docstring of on_click can be output.

[2]:
import ipywidgets as 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.

Examples#

Button clicks are stateless, i.e. they transfer messages from the front end to the back end. If you use the on_click method, a button will be displayed that will print the message as soon as it is clicked.

[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)

Traitlet events#

Widget properties are IPython traitlets. To make changes, the observe method of the widget can be used to register a callback. You can see the docstring for observe below.

You can find more information at Traitlet events.

[4]:
print(widgets.Widget.observe.__doc__)
Setup a handler to be called when a trait changes.

        This is used to setup dynamic notifications of trait changes.

        Parameters
        ----------
        handler : callable
            A callable that is called when a trait changes. Its
            signature should be ``handler(change)``, where ``change`` is a
            dictionary. The change dictionary at least holds a 'type' key.
            * ``type``: the type of notification.
            Other keys may be passed depending on the value of 'type'. In the
            case where type is 'change', we also have the following keys:
            * ``owner`` : the HasTraits instance
            * ``old`` : the old value of the modified trait attribute
            * ``new`` : the new value of the modified trait attribute
            * ``name`` : the name of the modified trait attribute.
        names : list, str, All
            If names is All, 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.
        type : str, All (default: 'change')
            The type of notification to filter by. If equal to All, then all
            notifications are passed to the observe handler.

Linking widgets#

To link widget attributes, you can simply link them together.

Linking traitlet attributes in the kernel#

[5]:
caption = widgets.Label(
    value="The values of slider1 and slider2 are synchronized"
)
sliders1, slider2 = widgets.IntSlider(
    description="Slider 1"
), widgets.IntSlider(description="Slider 2")
l = widgets.link((sliders1, "value"), (slider2, "value"))
display(caption, sliders1, slider2)

Linking widgets attributes on the client side#

There might be a delay while synchronizing Traitlet attributes due to communication with the server. However, you can also link the widget attributes to the link widgets directly in the browser. The Javascript links with jslink are retained even if widgets are embedded in HTML websites without a kernel.

[6]:
caption = widgets.Label(
    value="The values of range1 and range2 are synchronized"
)
range1, range2 = widgets.IntSlider(description="Range 1"), widgets.IntSlider(
    description="Range 2"
)
l = widgets.jslink((range1, "value"), (range2, "value"))
display(caption, range1, range2)
[7]:
caption = widgets.Label(
    value="Changes in source_range values are reflected in target_range1"
)
source_range, target_range1 = widgets.IntSlider(
    description="Source range"
), widgets.IntSlider(description="Target range 1")
dl = widgets.jsdlink((source_range, "value"), (target_range1, "value"))
display(caption, source_range, target_range1)

Continuous updates#

Some widgets offer a continuous_update attribute with the ability to continuously update values. In the following example we can see that the delayed controls only transmit their value after the user has dragged the slider or sent the text field. The continuous slides transfer their values continuously as soon as they are changed.

[8]:
a = widgets.IntSlider(description="Delayed", continuous_update=False)
b = widgets.IntText(description="Delayed", continuous_update=False)
c = widgets.IntSlider(description="Continuous", continuous_update=True)
d = widgets.IntText(description="Continuous", continuous_update=True)

widgets.link((a, "value"), (b, "value"))
widgets.link((a, "value"), (c, "value"))
widgets.link((a, "value"), (d, "value"))
widgets.VBox([a, b, c, d])