##// END OF EJS Templates
Example notebooks updated.
Example notebooks updated.

File last commit:

r14505:0aa8d337
r14505:0aa8d337
Show More
Part 2 - Events.ipynb
749 lines | 16.8 KiB | text/plain | TextLexer
In [2]:
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 [3]:
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 [5]:
intrange = widgets.IntRangeWidget()
display(intrange)

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

intrange.on_trait_change(on_value_change, 'value')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
20
19
18
17
16
12
10
8
6
4
3
2
1
4
10
18
39
60
68
75
79
82
85
86

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 [6]:
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 [7]:
display(intrange)
print('hi')
hi
85
84
81
79
73
70
67
59
56
53
51
49
47
45
44
42
In [8]:
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.
43
Button clicked.
44
Button clicked.
45
Button clicked.
46
Button clicked.
47
Button clicked.
48
Button clicked.
49

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 [9]:
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 [ ]: