##// END OF EJS Templates
Fixed flushed messages not getting sent with new 'method' message tag
Fixed flushed messages not getting sent with new 'method' message tag

File last commit:

r14446:81608774
r14451:8995edf8
Show More
Widget Tester.ipynb
278 lines | 11.1 KiB | text/plain | TextLexer
Jonathan Frederic
Added Widget Tester example
r14429 {
"metadata": {
"name": ""
},
"nbformat": 3,
"nbformat_minor": 0,
"worksheets": [
{
"cells": [
{
"cell_type": "code",
"collapsed": false,
"input": [
"from IPython.html import widgets\n",
"from IPython.display import display"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 1
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This notebook shows how widgets can be used to manipulate the properties of other widgets."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"To list the properties of a widget and allow the user to modify them, a function that keeps widgets in sync with traits is required. This function will syncronize a traitlet of one widget with a traitlet of another widget. The method also supports one way syncronization of types that have string representations with string traits."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def sync_widgets_properties(widget_a, property_a, widget_b, property_b, str_rep=False):\n",
" def set_property_a(name, old, new):\n",
" if old != new:\n",
" if str_rep:\n",
" setattr(widget_a, property_a, str(new))\n",
" else:\n",
" setattr(widget_a, property_a, new)\n",
" def set_property_b(name, old, new):\n",
" if old != new and not str_rep:\n",
" setattr(widget_b, property_b, new)\n",
" widget_a.on_trait_change(set_property_b, property_a)\n",
" widget_b.on_trait_change(set_property_a, property_b)\n",
" if str_rep:\n",
" setattr(widget_a, property_a, str(getattr(widget_b, property_b)))\n",
" else:\n",
" setattr(widget_a, property_a, getattr(widget_b, property_b))\n",
" \n",
" return widget_a"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 2
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This function will create a best match widget to represent a traitlet of another widget. The function will then bind the two widgets using the `sync_widget_properties` method above."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def create_hooked_widget(control, key):\n",
" property_type = type(getattr(control, key))\n",
" \n",
" if key == \"orientation\":\n",
" return sync_widgets_properties(widgets.SelectionWidget(values=['vertical', 'horizontal'], default_view_name='ToggleButtonsView'), 'value', control, key)\n",
" elif property_type is int:\n",
" return sync_widgets_properties(widgets.IntWidget(), 'value', control, key)\n",
" elif property_type is float:\n",
" return sync_widgets_properties(widgets.FloatWidget(), 'value', control, key)\n",
" elif property_type is bool:\n",
" return sync_widgets_properties(widgets.BoolWidget(), 'value', control, key)\n",
" elif property_type is str or property_type is unicode:\n",
" return sync_widgets_properties(widgets.StringWidget(), 'value', control, key)\n",
" else:\n",
" return sync_widgets_properties(widgets.StringWidget(disabled=True), 'value', control, key, str_rep=True)\n",
" "
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 3
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This function creates a modal that allows the user to read the doc string associated with a callable. The user can then invoke the callbable from the same modal."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"modals = {}\n",
"def get_method_modal(control, method_name, parent=None):\n",
" if not method_name in dir(control):\n",
" return None\n",
" if not control in modals:\n",
" modals[control] = {}\n",
" if not method_name in modals[control]:\n",
" new_modal = widgets.ContainerWidget(default_view_name=\"ModalView\")\n",
" new_modal.description=\"Invoke \" + method_name\n",
" new_modal.button_text = method_name + \"(...)\"\n",
" \n",
" doc_str = 'No doc string'\n",
" try:\n",
" doc_str = '<pre>' + getattr(control, method_name).__doc__ + '</pre>'\n",
" except:\n",
" pass\n",
" \n",
Jonathan Frederic
s/LabelView/HTMLView
r14446 " doc_label = widgets.StringWidget(parent=new_modal,default_view_name='HTMLView', value=doc_str)\n",
Jonathan Frederic
Added Widget Tester example
r14429 " doc_label.set_css('color', 'blue')\n",
" exec_box = widgets.ContainerWidget(parent=new_modal)\n",
" exec_box.hbox()\n",
" exec_box.pack_center()\n",
" exec_box.align_center()\n",
Jonathan Frederic
s/LabelView/HTMLView
r14446 " open_label = widgets.StringWidget(parent=exec_box,default_view_name='HTMLView', value=method_name+'(&nbsp;&nbsp;')\n",
Jonathan Frederic
Added Widget Tester example
r14429 " exec_str = widgets.StringWidget(parent=exec_box)\n",
Jonathan Frederic
s/LabelView/HTMLView
r14446 " close_label = widgets.StringWidget(parent=exec_box,default_view_name='HTMLView', value='&nbsp;&nbsp;)')\n",
Jonathan Frederic
Added Widget Tester example
r14429 " button_row = widgets.ContainerWidget(parent=new_modal)\n",
" button_row.hbox()\n",
" button_row.pack_end()\n",
" button_box = widgets.ContainerWidget(parent=button_row)\n",
" button_box.flex0()\n",
" exec_button = widgets.ButtonWidget(parent=button_box, description=\"Execute\")\n",
" \n",
" def handle_method_exec():\n",
" my_control = control\n",
" exec \"my_control.\" + method_name.replace('\\n', '') + \"(\" + exec_str.value + \")\" in globals(), locals()\n",
" exec_button.on_click(handle_method_exec)\n",
" exec_str.on_submit(handle_method_exec)\n",
" \n",
" if parent is not None:\n",
" new_modal.parent = parent\n",
" \n",
" modals[control][method_name] = new_modal\n",
" display(new_modal)\n",
" return modals[control][method_name]"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 4
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This function renders the control panel."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def hook_control(control, parent=None):\n",
" explorer = widgets.ContainerWidget()\n",
" if parent is not None:\n",
" explorer.parent = parent\n",
" explorer.hbox()\n",
" \n",
" viewer = widgets.ContainerWidget(parent=explorer)\n",
" viewer.set_css({\n",
" 'background': 'white',\n",
" 'border': '1px solid #000',\n",
" 'overflow': 'hidden',\n",
" })\n",
" viewer.flex2()\n",
" \n",
" control.parent = viewer\n",
" \n",
" side = widgets.ContainerWidget(parent=explorer)\n",
" side.flex1()\n",
" \n",
" side_tab = widgets.MulticontainerWidget(parent=side)\n",
" side_tab.set_css('margin', '5px')\n",
" \n",
" properties = widgets.ContainerWidget(parent=side_tab)\n",
" methods = widgets.ContainerWidget(parent=side_tab)\n",
" side_tab.set_title(0, 'Properties')\n",
" side_tab.set_title(1, 'Methods')\n",
" \n",
" for key in sorted(control.keys):\n",
" property_control = create_hooked_widget(control, key)\n",
" property_control.parent = properties\n",
" property_control.description = key + ':'\n",
" \n",
" methods.vbox()\n",
" methods.set_css('overflow', 'hidden')\n",
" \n",
" methods_container = widgets.ContainerWidget(parent=methods)\n",
" methods_container.flex1()\n",
" methods_buttons = widgets.ContainerWidget(parent=methods)\n",
" methods_buttons.flex0()\n",
" methods_buttons.hbox()\n",
" methods_buttons.pack_end()\n",
" methods_buttons.set_css({\n",
" 'padding-top': '5px',\n",
" 'padding-right': '50px',\n",
" })\n",
" \n",
" execute_button = widgets.ButtonWidget(parent=methods_buttons, description=\"Invoke\")\n",
" \n",
" method_list = widgets.SelectionWidget(parent=methods_container, default_view_name=\"ListBoxView\")\n",
" method_list.description = \"Names:\"\n",
" method_list.set_css('height', '400px')\n",
" method_list.values = [attr_name for attr_name in dir(control) if callable(getattr(control, attr_name)) and not attr_name.startswith('_')]\n",
" \n",
" def handle_execute_method():\n",
" get_method_modal(control, method_list.value, parent=parent)\n",
" execute_button.on_click(handle_execute_method)\n",
" \n",
" display(explorer) \n",
" explorer.add_class('well')\n",
" return explorer"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 5
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This final bit of code allows the user to select what control and view he/she wants to manipulate."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"control_tester = widgets.ContainerWidget()\n",
"widget_names = [widget_name for widget_name in dir(widgets) if widget_name.endswith('Widget') and widget_name != \"Widget\"]\n",
"widget_selector = widgets.SelectionWidget(parent=control_tester, description=\"Widget type:\", values=widget_names)\n",
"view_name = widgets.StringWidget(parent=control_tester, description=\"View name (optional):\")\n",
"display_button_container = widgets.ContainerWidget(parent=control_tester)\n",
"display_button_container.hbox()\n",
"display_button_container.pack_end()\n",
"display_button_container.set_css(\"padding\", \"5px\")\n",
"display_button = widgets.ButtonWidget(parent=display_button_container, description=\"Display\")\n",
"display(control_tester)\n",
"\n",
"last_displayed = [None]\n",
"def handle_display():\n",
" if last_displayed[0] is not None:\n",
" last_displayed[0].close()\n",
" widget_type = getattr(widgets, widget_selector.value)\n",
" widget = widget_type()\n",
" if len(view_name.value) > 0:\n",
" widget.default_view_name = view_name.value\n",
" last_displayed[0] = hook_control(widget)\n",
"display_button.on_click(handle_display)\n",
"view_name.on_submit(handle_display)\n"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 6
}
],
"metadata": {}
}
]
}