#!/usr/bin/env python # coding: utf-8 # [Index](Index.ipynb) - [Back](Widget Events.ipynb) - [Next](Custom Widget - Hello World.ipynb) # In[ ]: get_ipython().run_cell_magic('html', '', '\n') # In[ ]: from IPython.html import widgets from IPython.display import display # # Widget Styling # ## Basic styling # The widgets distributed with IPython can be styled by setting the following traits: # # - width # - height # - fore_color # - back_color # - border_color # - border_width # - border_style # - font_style # - font_weight # - font_size # - font_family # # The example below shows how a `Button` widget can be styled: # In[ ]: button = widgets.Button( description='Hello World!', width=100, # Integers are interpreted as pixel measurements. height='2em', # em is valid HTML unit of measurement. color='lime', # Colors can be set by name, background_color='#0022FF', # and also by color code. border_color='red') display(button) # ## Parent/child relationships # To display widget A inside widget B, widget A must be a child of widget B. Widgets that can contain other widgets have a **`children` attribute**. This attribute can be **set via a keyword argument** in the widget's constructor **or after construction**. Calling display on an **object with children automatically displays those children**, too. # In[ ]: from IPython.display import display float_range = widgets.FloatSlider() string = widgets.Text(value='hi') container = widgets.Box(children=[float_range, string]) container.border_color = 'red' container.border_style = 'dotted' container.border_width = 3 display(container) # Displays the `container` and all of it's children. # ### After the parent is displayed # Children **can be added to parents** after the parent has been displayed. The **parent is responsible for rendering its children**. # In[ ]: container = widgets.Box() container.border_color = 'red' container.border_style = 'dotted' container.border_width = 3 display(container) int_range = widgets.IntSlider() container.children=[int_range] # ## Fancy boxes # If you need to display a more complicated set of widgets, there are **specialized containers** that you can use. To display **multiple sets of widgets**, you can use an **`Accordion` or a `Tab` in combination with one `Box` per set of widgets** (as seen below). The "pages" of these widgets are their children. To set the titles of the pages, one can **call `set_title`**. # ### Accordion # In[ ]: name1 = widgets.Text(description='Location:') zip1 = widgets.BoundedIntText(description='Zip:', min=0, max=99999) page1 = widgets.Box(children=[name1, zip1]) name2 = widgets.Text(description='Location:') zip2 = widgets.BoundedIntText(description='Zip:', min=0, max=99999) page2 = widgets.Box(children=[name2, zip2]) accord = widgets.Accordion(children=[page1, page2], width=400) display(accord) accord.set_title(0, 'From') accord.set_title(1, 'To') # ### TabWidget # In[ ]: name = widgets.Text(description='Name:', padding=4) color = widgets.Dropdown(description='Color:', padding=4, options=['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet']) page1 = widgets.Box(children=[name, color], padding=4) age = widgets.IntSlider(description='Age:', padding=4, min=0, max=120, value=50) gender = widgets.RadioButtons(description='Gender:', padding=4, options=['male', 'female']) page2 = widgets.Box(children=[age, gender], padding=4) tabs = widgets.Tab(children=[page1, page2]) display(tabs) tabs.set_title(0, 'Name') tabs.set_title(1, 'Details') # # Alignment # Most widgets have a **`description` attribute**, which allows a label for the widget to be defined. # The label of the widget **has a fixed minimum width**. # The text of the label is **always right aligned and the widget is left aligned**: # In[ ]: display(widgets.Text(description="a:")) display(widgets.Text(description="aa:")) display(widgets.Text(description="aaa:")) # If a **label is longer** than the minimum width, the **widget is shifted to the right**: # In[ ]: display(widgets.Text(description="a:")) display(widgets.Text(description="aa:")) display(widgets.Text(description="aaa:")) display(widgets.Text(description="aaaaaaaaaaaaaaaaaa:")) # If a `description` is **not set** for the widget, the **label is not displayed**: # In[ ]: display(widgets.Text(description="a:")) display(widgets.Text(description="aa:")) display(widgets.Text(description="aaa:")) display(widgets.Text()) # ## Flex boxes # Widgets can be aligned using the `FlexBox`, `HBox`, and `VBox` widgets. # ### Application to widgets # Widgets display vertically by default: # In[ ]: buttons = [widgets.Button(description=str(i)) for i in range(3)] display(*buttons) # ### Using hbox # To make widgets display horizontally, you need to **child them to a `HBox` widget**. # In[ ]: container = widgets.HBox(children=buttons) display(container) # By setting the width of the container to 100% and its `pack` to `center`, you can center the buttons. # In[ ]: container.width = '100%' container.pack = 'center' # ## Visibility # Sometimes it is necessary to **hide or show widgets** in place, **without having to re-display** the widget. # The `visible` property of widgets can be used to hide or show **widgets that have already been displayed** (as seen below). The `visible` property can be: # * `True` - the widget is displayed # * `False` - the widget is hidden, and the empty space where the widget would be is collapsed # * `None` - the widget is hidden, and the empty space where the widget would be is shown # In[ ]: w1 = widgets.Latex(value="First line") w2 = widgets.Latex(value="Second line") w3 = widgets.Latex(value="Third line") display(w1, w2, w3) # In[ ]: w2.visible=None # In[ ]: w2.visible=False # In[ ]: w2.visible=True # ### Another example # 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[ ]: form = widgets.VBox() first = widgets.Text(description="First Name:") last = widgets.Text(description="Last Name:") student = widgets.Checkbox(description="Student:", value=False) school_info = widgets.VBox(visible=False, children=[ widgets.Text(description="School:"), widgets.IntText(description="Grade:", min=0, max=12) ]) pet = widgets.Text(description="Pet's Name:") form.children = [first, last, student, school_info, pet] 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') # [Index](Index.ipynb) - [Back](Widget Events.ipynb) - [Next](Custom Widget - Hello World.ipynb)