In [1]:
import os,sys
sys.path.insert(0, os.path.abspath('..'))
import hublib.ui as ui


Number (Float) Input with Units


In [2]:
e1 = ui.Number(
        name='E1',
        description="Longitudinal Young's Modulus",
        units='GPa',
        min=0,
        max=500,
        value=138
)
e1



In [3]:
def my_cb(x, y):
    print("CB:", x == e1)
    print("New:", y)
def my_cb2(x, y):
    print("CB2:", x == e1)
    print("New:", y)

You can control the width. But it is generally better to use Layout.


In [4]:
e2 = ui.Number(
        name='E1',
        description="Longitudinal Young's Modulus",
        units='GPa',
        min=0,
        max=500,
        value=138,
        cb=my_cb,
        width='30%'
    )
e2



In [5]:
e2.value=170


('CB:', False)
('New:', 170.0)

In [6]:
e2.min = 150

In [7]:
e2.cb  = my_cb2

Integer Input

Integer inputs do not have units


In [8]:
e2 = ui.Integer(
        name='Loops',
        desc="Number of Loops to Run",
        min=0,
        max=500,
        value=1
    )
e2


Checkbutton


In [9]:
check = ui.Checkbox('Advanced Options', desc='Show the Advanced Options', value=False)
check



In [10]:
check.value


Out[10]:
False

Radiobutton


In [11]:
r = ui.Radiobuttons(
            name='Nut',
            description="Type of nut to eat.",
            value='almond',
            options=['peanut', 'walnut', 'almond', 'pecan']
)
r


Togglebutton


In [12]:
tb = ui.Togglebuttons(
            name='Nut',
            description="Type of nut to eat.",
            value='almond',
            options=['peanut', 'walnut', 'almond', 'pecan'],
        )
tb



In [13]:
dd = ui.Dropdown(
            name='Nut',
            description="Type of nut to eat.",
            value='almond',
            options=['peanut', 'walnut', 'almond', 'pecan']
)
dd



In [14]:
xstr = ui.String(name="Name", description='Name (First and Last)', value='<name>')
xstr



In [15]:
# FIXME. Width

xtxt = ui.Text(name="Description", description='Experiment Description', value='')
xtxt


Grouping

Collections of UI elements can be collected in Tabs and Forms.


In [16]:
ui.Tab([e1,tb,xstr])



In [17]:
ui.Form([e1,tb,xstr])



In [18]:
f1 = ui.Form([e1,tb,xstr], name='My Parameters')
f1



In [19]:
f2 = ui.Form([check, dd, xtxt], name='More Parameters', width='50%')
f2



In [20]:
ui.Tab([f1,f2])

# FIXME: What about a Form without a title?  Box?  Group? or Form(name='')



In [21]:
# FIXME: What about colors for forms? everything?
ff = ui.Form([f1,f2])
ff



In [22]:
f1 = ui.Form([e1,tb,xstr])
f2 = ui.Form([check, dd, xtxt])
ui.Tab([f1,f2], titles=['My Parameters', 'More Parameters'])


Disable UI Elements

You can disable individual elements or all the elements in a Form or Tab.


In [23]:
ff.disabled = True

In [24]:
ff.disabled = False

Visibility

You can make elements visible or invisible.


In [25]:
#tb.visible = False

In [26]:
#tb.visible = True

Callbacks

Each non-grouping UI element can callback a function you provide when the value changes.


In [27]:
def something_changed(name, value):
    print("%s changed to %s" % (name, value))

tbc = ui.Togglebuttons(
            name='Nut',
            description="Type of nut to eat.",
            value='almond',
            options=['peanut', 'walnut', 'almond', 'pecan'],
            cb=something_changed,
            width='50%'
        )
tbc


Interactive UI

We can use callbacks to modify the UI dynamically.

Disabling Elements


In [28]:
def set_advanced(name, val):
    opt.disabled = not val

adv_check = ui.Checkbox('Advanced Options', desc='Show the Advanced Options', value=False, cb=set_advanced)

opt = ui.Togglebuttons(
            name='Options',
            description="Nut Options",
            value='None',
            options=['None', 'Toasted', 'Roasted', 'Glazed', 'Salted'],
            disabled=True,  # initial state
        )
ui.Form([adv_check, tb, opt])


Hiding Elements Dynamically


In [29]:
def show_advanced(name, val):
    opt.visible = val

adv_check = ui.Checkbox('Advanced Options', desc='Show the Advanced Options', value=False, width='50%', cb=show_advanced)
opt.visible = False
ui.Form([adv_check, tb, opt])


A More Complicated Example


In [30]:
ice_cream = ui.Dropdown(
            name='Ice Cream',
            description="Ice Cream Flavor.",
            value='Vanilla',
            options=['Vanilla', 'Strawberry', 'Chocolate', 'Pistachio'],
        )
topping = ui.Radiobuttons(
            name='Topping',
            description="Ice Cream Topping",
            value='None',
            options=['None', 'Fudge', 'Caramel', 'Marshmallow'],
        )
cherry = ui.Checkbox('Cherry', desc='Cherry on Top?', value=False)
brownie = ui.Togglebuttons('Brownie', desc="Brownie on the bottom?", value='No', options=['No', 'Yes'])
sundae = ui.Group([ice_cream, topping, brownie, cherry], name='Sundae', desc='Not a day of the week!', width='50%')
sundae



In [ ]:


In [31]:
crust = ui.Dropdown(
            name='Crust',
            description="Pizza Crust",
            value='Thin',
            options=['Thin', 'Hand-Tossed', 'Pan', 'Gluten-Free'],
        )
sauce = ui.Dropdown(
            name='Sauce',
            description="Sauce Type",
            value='Regular',
            options=['Regular', 'Robust', 'Pesto'],
        )
cheese = ui.Checkbox('Extra Cheese', value=False)
pizza = ui.Form([crust, sauce, cheese], name='', width='50%') # collapsible
pizza



In [32]:
ui.Tab([pizza, sundae])



In [33]:
# HBox to do multicolumns
# Accordion (collapsible form)
# Form -> Group??
import ipywidgets as widgets
layoutL=widgets.Layout(
            display='flex',
            flex_flow='column',
            align_items='stretch',
            width='100%',
            padding='0 10px 0 0'
        )
layoutR=widgets.Layout(
            display='flex',
            flex_flow='column',
            align_items='stretch',
            width='50%',
#             padding='0 0 0 5px'
        )
sundae.layout = layoutL
pizza.layout = layoutR
widgets.HBox([sundae, pizza])


maybe smart layout? check widths and adjust size accordingly

Use width% or widgets.HBox([sundae, pizza], size=[2,1])


In [34]:
pizza.layout.width


Out[34]:
u'50%'

In [35]:
accordion = widgets.Accordion(children=[pizza, sundae])
accordion.set_title(0, 'Pizza')
accordion.set_title(1, 'Sundae')
accordion



In [36]:
accordion.selected_index=None

In [37]:
a = ['hello', 'world', 'martin', 'hunt']
a[1:]


Out[37]:
['world', 'martin', 'hunt']

In [38]:
a.appendleft('123')
a


---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-38-ff4166901048> in <module>()
----> 1 a.appendleft('123')
      2 a

AttributeError: 'list' object has no attribute 'appendleft'

In [ ]: