##// END OF EJS Templates
Remove init_widget_js, use require.js for everything...
Remove init_widget_js, use require.js for everything Updated examples Fixed bug with message throttling

File last commit:

r14342:90efa5b8
r14342:90efa5b8
Show More
Part 3 - Placement.ipynb
257 lines | 8.1 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

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')