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()
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).
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.
container = widgets.MulticontainerWidget()
display(container)
intrange = widgets.IntRangeWidget(parent=container) # Never gets displayed.
Calling display on the child fixes the problem.
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_name
s can't be set since all of the widgets are sharing the same display call. Instead, their default_view_name
s must be set (as seen below).
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.
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).
string = widgets.StringWidget(value="Hello World!")
display(string, view_name="LabelView")
string.visible=False
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.
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')