{ "metadata": { "cell_tags": [ [ "", null ] ], "name": "" }, "nbformat": 3, "nbformat_minor": 0, "worksheets": [ { "cells": [ { "cell_type": "code", "collapsed": false, "input": [ "from __future__ import print_function # 2.7 compatability\n", "\n", "from IPython.html import widgets # Widget definitions\n", "from IPython.display import display # Used to display widgets in the notebook" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 2 }, { "cell_type": "heading", "level": 1, "metadata": {}, "source": [ "Traitlet Events" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "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." ] }, { "cell_type": "code", "collapsed": false, "input": [ "print(widgets.Widget.on_trait_change.__doc__)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Setup a handler to be called when a trait changes.\n", "\n", " This is used to setup dynamic notifications of trait changes.\n", "\n", " Static handlers can be created by creating methods on a HasTraits\n", " subclass with the naming convention '_[traitname]_changed'. Thus,\n", " to create static handler for the trait 'a', create the method\n", " _a_changed(self, name, old, new) (fewer arguments can be used, see\n", " below).\n", "\n", " Parameters\n", " ----------\n", " handler : callable\n", " A callable that is called when a trait changes. Its\n", " signature can be handler(), handler(name), handler(name, new)\n", " or handler(name, old, new).\n", " name : list, str, None\n", " If None, the handler will apply to all traits. If a list\n", " of str, handler will apply to all names in the list. If a\n", " str, the handler will apply just to that name.\n", " remove : bool\n", " If False (the default), then install the handler. If True\n", " then unintall it.\n", " \n" ] } ], "prompt_number": 3 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Mentioned in the doc string, the callback registered can have 4 possible signatures:\n", "\n", "- callback()\n", "- callback(trait_name)\n", "- callback(trait_name, new_value)\n", "- callback(trait_name, old_value, new_value)\n", "\n", "An example of how to output an IntRangeWiget's value as it is changed can be seen below." ] }, { "cell_type": "code", "collapsed": false, "input": [ "intrange = widgets.IntRangeWidget()\n", "display(intrange)\n", "\n", "def on_value_change(name, value):\n", " print(value)\n", "\n", "intrange.on_trait_change(on_value_change, 'value')" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "1\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "2\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "3\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "4\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "5\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "6\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "7\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "8\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "9\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "10\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "11\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "12\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "13\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "14\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "15\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "16\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "17\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "18\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "20\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "19\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "18\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "17\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "16\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "12\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "10\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "8\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "6\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "4\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "3\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "2\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "1\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "4\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "10\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "18\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "39\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "60\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "68\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "75\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "79\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "82\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "85\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "86\n" ] } ], "prompt_number": 5 }, { "cell_type": "heading", "level": 1, "metadata": {}, "source": [ "Specialized Events" ] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Button On Click Event" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "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." ] }, { "cell_type": "code", "collapsed": false, "input": [ "print(widgets.ButtonWidget.on_click.__doc__)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Register a callback to execute when the button is clicked. The\n", " callback can either accept no parameters or one sender parameter:\n", " - callback()\n", " - callback(sender)\n", " If the callback has a sender parameter, the ButtonWidget instance that\n", " called the callback will be passed into the method as the sender.\n", "\n", " Parameters\n", " ----------\n", " remove : bool (optional)\n", " Set to true to remove the callback from the list of callbacks.\n" ] } ], "prompt_number": 6 }, { "cell_type": "markdown", "metadata": {}, "source": [ "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." ] }, { "cell_type": "code", "collapsed": false, "input": [ "display(intrange)\n", "print('hi')" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "hi\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "85\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "84\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "81\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "79\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "73\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "70\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "67\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "59\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "56\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "53\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "51\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "49\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "47\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "45\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "44\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "42\n" ] } ], "prompt_number": 7 }, { "cell_type": "code", "collapsed": false, "input": [ "button = widgets.ButtonWidget(description=\"Click Me!\")\n", "display(button)\n", "\n", "def on_button_clicked(sender):\n", " print(\"Button clicked.\")\n", " intrange.value +=1\n", "\n", "button.on_click(on_button_clicked)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Button clicked.\n", "43\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "Button clicked.\n", "44\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "Button clicked.\n", "45\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "Button clicked.\n", "46\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "Button clicked.\n", "47\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "Button clicked.\n", "48\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "Button clicked.\n", "49\n" ] } ], "prompt_number": 8 }, { "cell_type": "markdown", "metadata": {}, "source": [ "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." ] }, { "cell_type": "code", "collapsed": false, "input": [], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 11, "text": [ "{'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\",\n", " 'name': 'stdout'},\n", " 'header': {'msg_id': 'd9dc144a-d86c-42c1-8bab-f8a6bc525723',\n", " 'msg_type': 'stream',\n", " 'session': '9b9408d8-7420-4e0c-976d-cdda9f8d2564',\n", " 'username': 'kernel'},\n", " 'metadata': {},\n", " 'msg_id': 'd9dc144a-d86c-42c1-8bab-f8a6bc525723',\n", " 'msg_type': 'stream',\n", " 'parent_header': {'msg_id': '3DBB06AD83C942DD85DC6477B08F1FBF',\n", " 'msg_type': 'comm_msg',\n", " 'session': '0F6D6BE728DA47A38CFC4BDEACF34FC4',\n", " 'username': 'username'}}" ] } ], "prompt_number": 11 }, { "cell_type": "code", "collapsed": false, "input": [ "def show_button(sender=None):\n", " button = widgets.ButtonWidget()\n", " button.clicks = 0\n", " if sender is None:\n", " button.description = \"0\"\n", " else:\n", " sender.clicks += 1\n", " button.description = \"%d\" % sender.clicks\n", " display(button)\n", " button.on_click(show_button)\n", "show_button()\n", " " ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 9 }, { "cell_type": "code", "collapsed": false, "input": [], "language": "python", "metadata": {}, "outputs": [] } ], "metadata": {} } ] }