##// END OF EJS Templates
update example notebooks
update example notebooks

File last commit:

r14619:eea2b793
r14619:eea2b793
Show More
Part 2 - Events.ipynb
661 lines | 15.3 KiB | text/plain | TextLexer
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

The widget properties are IPython traitlets. Traitlets are eventful. To handle property value changes, the on_trait_change method of the widget can be used to register an event handling callback. The doc string 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)

An example of how to output an IntRangeWiget's value as it is changed can be seen below.

In [3]:
intrange = widgets.IntRangeWidget()
display(intrange)

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

intrange.on_trait_change(on_value_change, 'value')
2
5
10
11
13
14
16
18
20
22
24
26
29
30
33
36
38
42
45
46
48
50
51
52
53
54
52
50
48
44
41
34
30
28
26
25
24

Specialized Events

Button On Click Event

The ButtonWidget is a special widget, like the ContainerWidget and MulticontainerWidget, 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 a click even handler. The doc string 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 can either accept no parameters or one sender parameter:
        - callback()
        - callback(sender)
        If the callback has a sender parameter, the ButtonWidget instance that
        called the callback will be passed into the method as the sender.

        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]:
display(intrange)
print('hi')
hi
23
24
28
30
37
39
41
44
46
48
50
51
53
In [6]:
button = widgets.ButtonWidget(description="Click Me!")
display(button)

def on_button_clicked(sender):
    print("Button clicked.")
    intrange.value +=1

button.on_click(on_button_clicked)
Button clicked.
54
Button clicked.
55
Button clicked.
56

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 [11]:
 
Out[11]:
{'content': {'data': "{'parent_header': {}, 'msg_type': u'comm_msg', 'msg_id': u'3DBB06AD83C942DD85DC6477B08F1FBF', 'content': {u'data': {u'method': u'custom', u'custom_content': {u'event': u'click'}}, u'comm_id': u'eea5f11ae7aa473993dd0c81d6016648'}, 'header': {u'username': u'username', u'msg_id': u'3DBB06AD83C942DD85DC6477B08F1FBF', u'msg_type': u'comm_msg', u'session': u'0F6D6BE728DA47A38CFC4BDEACF34FC4'}, 'buffers': [], 'metadata': {}}\ncustom message {'parent_header': {}, 'msg_type': u'comm_msg', 'msg_id': u'3DBB06AD83C942DD85DC6477B08F1FBF', 'content': {u'data': {u'method': u'custom', u'custom_content': {u'event': u'click'}}, u'comm_id': u'eea5f11ae7aa473993dd0c81d6016648'}, 'header': {u'username': u'username', u'msg_id': u'3DBB06AD83C942DD85DC6477B08F1FBF', u'msg_type': u'comm_msg', u'session': u'0F6D6BE728DA47A38CFC4BDEACF34FC4'}, 'buffers': [], 'metadata': {}}\nhandling click\n{u'event': u'click'}\nButton clicked.\n2\n",
  'name': 'stdout'},
 'header': {'msg_id': 'd9dc144a-d86c-42c1-8bab-f8a6bc525723',
  'msg_type': 'stream',
  'session': '9b9408d8-7420-4e0c-976d-cdda9f8d2564',
  'username': 'kernel'},
 'metadata': {},
 'msg_id': 'd9dc144a-d86c-42c1-8bab-f8a6bc525723',
 'msg_type': 'stream',
 'parent_header': {'msg_id': '3DBB06AD83C942DD85DC6477B08F1FBF',
  'msg_type': 'comm_msg',
  'session': '0F6D6BE728DA47A38CFC4BDEACF34FC4',
  'username': 'username'}}
In [7]:
def show_button(sender=None):
    button = widgets.ButtonWidget()
    button.clicks = 0
    if sender is None:
        button.description = "0"
    else:
        sender.clicks += 1
        button.description = "%d" % sender.clicks
    display(button)
    button.on_click(show_button)
show_button()
    
In [ ]: