##// END OF EJS Templates
flush replies when entering an eventloop...
flush replies when entering an eventloop avoids possible hangs when the GUI eventloop prevents queued replies from being sent

File last commit:

r14834:5ed93769
r15232:158d7616
Show More
Part 2 - Events.ipynb
260 lines | 7.4 KiB | text/plain | TextLexer

[< Back to Part 1](Part 1 - Basics.ipynb) or Index

In [1]:
from __future__ import print_function # 2.7 compatability

from IPython.html import widgets # Widget definitions
from IPython.display import display # Used to display widgets in the notebook

Traitlet Events

As mentioned in Part 1, the widget attributes are IPython traitlets. Traitlets are eventful. To handle changes, the on_trait_change method of the widget can be used to register a callback. The docstring for on_trait_change can be seen below. Both the name and remove properties are optional.

In [2]:
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.
        

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 IntSliderWiget's value as it is changed can be seen below.

In [3]:
int_range = widgets.IntSliderWidget()
display(int_range)

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

int_range.on_trait_change(on_value_change, 'value')

Specialized Events

Button Click Event

The ButtonWidget is a special widget, like the ContainerWidget and TabWidget, that isn't used to represent a data type. Instead the button widget is used to handle mouse clicks. The on_click method of the ButtonWidget can be used to register function to be called when the button is clicked. The docstring of the on_click can be seen below.

In [4]:
print(widgets.ButtonWidget.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.

Button clicks 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 [5]:
button = widgets.ButtonWidget(description="Click Me!")
display(button)

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

button.on_click(on_button_clicked)
Button clicked.
Button clicked.
Button clicked.

Event handlers can also be used to create widgets. In the example below, clicking a button spawns another button with a description equal to how many times the parent button had been clicked at the time.

In [6]:
def new_button(clicked):
    button = widgets.ButtonWidget()
    button.clicks = 0
    clicked.clicks += 1
    button.description = "%d" % clicked.clicks
    display(button)
    button.on_click(new_button)
button = widgets.ButtonWidget(description = "Start")
button.clicks = 0
display(button)
button.on_click(new_button)
    

In [Part 3](Part 3 - Placement.ipynb) of this series, you will learn about widget placement.