##// END OF EJS Templates
Fix: added inspect import to widget.py
Fix: added inspect import to widget.py

File last commit:

r14327:af45ffd0
r14341:c0c9ab2c
Show More
Part 3 - Placement.ipynb
325 lines | 9.9 KiB | text/plain | TextLexer
/ examples / widgets / Part 3 - Placement.ipynb
In [1]:
from IPython.html import widgets # Widget definitions
from IPython.display import display # Used to display widgets in the notebook

# Enable widgets in this notebook
widgets.init_widget_js()
SandBoxed(IPython.core.display.Javascript object)
SandBoxed(IPython.core.display.Javascript object)
SandBoxed(IPython.core.display.Javascript object)
SandBoxed(IPython.core.display.Javascript object)
SandBoxed(IPython.core.display.Javascript object)
SandBoxed(IPython.core.display.Javascript object)
SandBoxed(IPython.core.display.Javascript object)
SandBoxed(IPython.core.display.Javascript object)
SandBoxed(IPython.core.display.Javascript object)
SandBoxed(IPython.core.display.Javascript object)

Parent/Child Relationships

To display widget A inside widget B, widget A must be a child of widget B. With IPython widgets, the widgets are instances that live in the back-end (usally Python). There can be multiple views displayed in the front-end that represent one widget in the backend. Each view can be displayed at a different time, or even displayed two or more times in the same output. Because of this, the parent of a widget can only be set before the widget has been displayed.

Every widget has a parent property. This property can be set via a kwarg in the widget's constructor or after construction, but before display. Calling display on an object with children automatically displays those children too (as seen below).

In [2]:
container = widgets.MulticontainerWidget()

floatrange = widgets.FloatRangeWidget(parent=container) # You can set the parent in the constructor,

string = widgets.StringWidget()
string.parent = container # or after the widget has been created.

display(container) # Displays the `container` and all of it's children.

Children can also be added to parents after the parent has been displayed. If the children are added after the parent has already been displayed, the children must be displayed themselves.

In the example below, the IntRangeWidget is never rendered since display was called on the parent before the parent/child relationship was established.

In [3]:
container = widgets.MulticontainerWidget()
display(container)

intrange = widgets.IntRangeWidget(parent=container) # Never gets displayed.

Calling display on the child fixes the problem.

In [4]:
container = widgets.MulticontainerWidget()
display(container)

intrange = widgets.IntRangeWidget(parent=container)
display(intrange) # This line is needed since the `container` has already been displayed.

Changing Child Views

The view used to display a widget must defined by the time the widget is displayed. If children widgets are to be displayed along with the parent in one call, their view_names can't be set since all of the widgets are sharing the same display call. Instead, their default_view_names must be set (as seen below).

In [5]:
container = widgets.MulticontainerWidget()

floatrange = widgets.FloatRangeWidget(parent=container)
floatrange.default_view_name = "FloatTextView" # It can be set as a property.

string = widgets.StringWidget(default_view_name = "TextAreaView") # It can also be set in the constructor.
string.parent = container

display(container)

However, if the children are displayed after the parent, their view_name can also be set like normal. Both methods will work. The code below produces the same output as the code above.

In [6]:
container = widgets.MulticontainerWidget()
display(container)

floatrange = widgets.FloatRangeWidget()
floatrange.parent=container
display(floatrange, view_name = "FloatTextView") # view_name can be set during display.

string = widgets.StringWidget()
string.parent = container
string.default_view_name = "TextAreaView" # Setting default_view_name still works.
display(string)

Visibility

Sometimes it's necessary to hide/show widget views in place, without ruining the order that they have been displayed on the page. Using the display method, the views are always added to the end of their respective containers. Instead the visibility property of widgets can be used to hide/show widgets that have already been displayed (as seen below).

In [7]:
string = widgets.StringWidget(value="Hello World!")
display(string, view_name="LabelView") 
In [8]:
string.visible=False
In [9]:
string.visible=True

In the example below, a form is rendered which conditionally displays widgets depending on the state of other widgets. Try toggling the student checkbox.

In [10]:
form = widgets.ContainerWidget()
first = widgets.StringWidget(description="First Name:", parent=form)
last = widgets.StringWidget(description="Last Name:", parent=form)

student = widgets.BoolWidget(description="Student:", value=False, parent=form)
school_info = widgets.ContainerWidget(visible=False, parent=form)
school = widgets.StringWidget(description="School:", parent=school_info)
grade = widgets.IntRangeWidget(description="Grade:", min=0, max=12, default_view_name='IntTextView', parent=school_info)

pet = widgets.StringWidget(description="Pet's Name:", parent=form)
display(form)

def on_student_toggle(name, value):
    if value:
        school_info.visible = True
    else:
        school_info.visible = False
student.on_trait_change(on_student_toggle, 'value')