Source code for openmdao.visualization.options_widget

"""
A widget-based representation of OptionsDictionary for use in Jupyter notebooks.
"""

try:
    import ipywidgets as widgets
    from ipywidgets import Layout
    from IPython.display import display
except Exception:
    widgets = None

from openmdao.utils.om_warnings import issue_warning


[docs]class OptionsWidget(object): """ Widget to set options. Parameters ---------- opts : OptionsDictionary Options to edit. """
[docs] def __init__(self, opts): """ Initialize. """ if widgets is None: issue_warning(f"ipywidgets is required to use {self.__class__.__name__}." "To install it run `pip install openmdao[notebooks]`.") return _dict = opts._dict _widgets = [] _style = {'description_width': 'initial', 'align-items': 'center'} messages = widgets.Output() @messages.capture(clear_output=True) def option_changed(change): owner = change['owner'] newval = change['new'] name = owner.description option = _dict[name] # if it's an arbitrary list, parse lines of text if option['types'] is list and option['values'] is None: newval = newval.strip().split('\n') try: option['val'] = newval except ValueError as err: print(str(err)) for name, option in sorted(_dict.items()): val = option['val'] types = option['types'] values = option['values'] desc = option['desc'] if values: if types is list: _widgets.append(widgets.SelectMultiple( description=name, tooltip=desc, options=sorted(values), value=val, disabled=False, style=_style )) continue else: _widgets.append(widgets.Dropdown( description=name, tooltip=desc, options=values, value=val, disabled=False, style=_style )) continue upper = option['upper'] lower = option['lower'] if upper and lower: if isinstance(val, int): _widgets.append(widgets.IntSlider( description=name, tooltip=desc, min=lower, max=upper, value=val, step=1, disabled=False, continuous_update=False, orientation='horizontal', readout=True, readout_format='d', style=_style )) else: _widgets.append(widgets.FloatSlider( description=name, tooltip=desc, min=lower, max=upper, value=val, disabled=False, continuous_update=False, orientation='horizontal', readout=True, readout_format='f', style=_style )) continue if isinstance(val, float): _widgets.append(widgets.FloatText( description=name, tooltip=desc, min=lower, max=upper, value=val, disabled=False, continuous_update=False, orientation='horizontal', readout=True, readout_format='f', style=_style )) continue if isinstance(val, int): _widgets.append(widgets.IntText( description=name, tooltip=desc, min=lower, max=upper, value=val, step=1, disabled=False, continuous_update=False, orientation='horizontal', readout=True, readout_format='d', style=_style )) continue types = option['types'] if isinstance(types, list): _widgets.append(widgets.Textarea( description=name, tooltip=desc, value='\n'.join(val), continuous_update=False, rows=5, disabled=False, style=_style )) continue # unhandled option type, just show value as uneditable text _widgets.append(widgets.Textarea( description=name, tooltip=desc, value=str(val), disabled=True, style=_style )) for wdgt in _widgets: wdgt.observe(option_changed, 'value') # sort widgets by how many rows they use _wdgt_rows = [(wdgt.rows if getattr(wdgt, 'rows', None) else 1, wdgt) for wdgt in _widgets] _wdgt_rows.sort(key=lambda x: x[0]) _widgets = [wdgt for _, wdgt in _wdgt_rows] box_layout = Layout(display='flex', flex_flow='row wrap') display(widgets.GridBox(children=_widgets, layout=box_layout)) display(messages)