"There are many widgets distributed with ipywidgets that are designed to display numeric values. Widgets exist for displaying integers and floats, both bounded and unbounded. The integer widgets share a similar naming scheme to their floating point counterparts. By replacing `Float` with `Int` in the widget name, you can find the Integer equivalent."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### IntSlider \n",
"- The slider is displayed with a specified, initial `value`. Lower and upper bounds are defined by `min` and `max`, and the value can be incremented according to the `step` parameter.\n",
"- The slider's label is defined by `description` parameter \n",
"- The slider's `orientation` is either 'horizontal' (default) or 'vertical'\n",
"- `readout` displays the current value of the slider next to it. The options are **True** (default) or **False** \n",
" - `readout_format` specifies the format function used to represent slider value. The default is '.2f'\n",
"The `FloatLogSlider` has a log scale, which makes it easy to have a slider that covers a wide range of positive magnitudes. The `min` and `max` refer to the minimum and maximum exponents of the `base`, and the `value` refers to the actual value of the slider."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"widgets.FloatLogSlider(\n",
" value=10,\n",
" base=10,\n",
" min=-10, # max exponent of base\n",
" max=10, # min exponent of base\n",
" step=0.2, # exponent step\n",
" description='Log Slider'\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### IntRangeSlider"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"widgets.IntRangeSlider(\n",
" value=[5, 7],\n",
" min=0,\n",
" max=10,\n",
" step=1,\n",
" description='Test:',\n",
" disabled=False,\n",
" continuous_update=False,\n",
" orientation='horizontal',\n",
" readout=True,\n",
" readout_format='d',\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### FloatRangeSlider"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"widgets.FloatRangeSlider(\n",
" value=[5, 7.5],\n",
" min=0,\n",
" max=10.0,\n",
" step=0.1,\n",
" description='Test:',\n",
" disabled=False,\n",
" continuous_update=False,\n",
" orientation='horizontal',\n",
" readout=True,\n",
" readout_format='.1f',\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### IntProgress"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"widgets.IntProgress(\n",
" value=7,\n",
" min=0,\n",
" max=10,\n",
" description='Loading:',\n",
" bar_style='', # 'success', 'info', 'warning', 'danger' or ''\n",
" style={'bar_color': 'maroon'},\n",
" orientation='horizontal'\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### FloatProgress"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"widgets.FloatProgress(\n",
" value=7.5,\n",
" min=0,\n",
" max=10.0,\n",
" description='Loading:',\n",
" bar_style='info',\n",
" style={'bar_color': '#ffff00'},\n",
" orientation='horizontal'\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The numerical text boxes that impose some limit on the data (range, integer-only) impose that restriction when the user presses enter.\n",
"\n",
"### BoundedIntText"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"widgets.BoundedIntText(\n",
" value=7,\n",
" min=0,\n",
" max=10,\n",
" step=1,\n",
" description='Text:',\n",
" disabled=False\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### BoundedFloatText"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"widgets.BoundedFloatText(\n",
" value=7.5,\n",
" min=0,\n",
" max=10.0,\n",
" step=0.1,\n",
" description='Text:',\n",
" disabled=False\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### IntText"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"widgets.IntText(\n",
" value=7,\n",
" description='Any:',\n",
" disabled=False\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### FloatText"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"widgets.FloatText(\n",
" value=7.5,\n",
" description='Any:',\n",
" disabled=False\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## Boolean widgets"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"There are three widgets that are designed to display a boolean value."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### ToggleButton"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"widgets.ToggleButton(\n",
" value=False,\n",
" description='Click me',\n",
" disabled=False,\n",
" button_style='', # 'success', 'info', 'warning', 'danger' or ''\n",
" tooltip='Description',\n",
" icon='check' # (FontAwesome names without the `fa-` prefix)\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Checkbox \n",
"- `value` specifies the value of the checkbox\n",
"- `indent` parameter places an indented checkbox, aligned with other controls. Options are **True** (default) or **False** \n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"widgets.Checkbox(\n",
" value=False,\n",
" description='Check me',\n",
" disabled=False,\n",
" indent=False\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Valid\n",
"\n",
"The valid widget provides a read-only indicator."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"widgets.Valid(\n",
" value=False,\n",
" description='Valid!',\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## Selection widgets"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"There are several widgets that can be used to display single selection lists, and two that can be used to select multiple values. All inherit from the same base class. You can specify the **enumeration of selectable options by passing a list** (options are either (label, value) pairs, or simply values for which the labels are derived by calling `str`).\n",
"\n",
"<div class=\"alert alert-info\">\n",
"Changes in *ipywidgets 8*:\n",
" \n",
"Selection widgets no longer accept a dictionary of options. Pass a list of key-value pairs instead.\n",
"# value='pineapple', # Defaults to 'pineapple'\n",
"# layout={'width': 'max-content'}, # If the items' names are long\n",
" description='Pizza topping:',\n",
" disabled=False\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### With dynamic layout and very long labels"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"widgets.Box(\n",
" [\n",
" widgets.Label(value='Pizza topping with a very long label:'), \n",
" widgets.RadioButtons(\n",
" options=[\n",
" 'pepperoni', \n",
" 'pineapple', \n",
" 'anchovies', \n",
" 'and the long name that will fit fine and the long name that will fit fine and the long name that will fit fine '\n",
" ],\n",
" layout={'width': 'max-content'}\n",
" )\n",
" ]\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Select"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"widgets.Select(\n",
" options=['Linux', 'Windows', 'OSX'],\n",
" value='OSX',\n",
" # rows=10,\n",
" description='OS:',\n",
" disabled=False\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### SelectionSlider"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"widgets.SelectionSlider(\n",
" options=['scrambled', 'sunny side up', 'poached', 'over easy'],\n",
" value='sunny side up',\n",
" description='I like my eggs ...',\n",
" disabled=False,\n",
" continuous_update=False,\n",
" orientation='horizontal',\n",
" readout=True\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### SelectionRangeSlider\n",
"\n",
"The value, index, and label keys are 2-tuples of the min and max values selected. The options must be nonempty."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import datetime\n",
"dates = [datetime.date(2015, i, 1) for i in range(1, 13)]\n",
"options = [(i.strftime('%b'), i) for i in dates]\n",
"widgets.SelectionRangeSlider(\n",
" options=options,\n",
" index=(0, 11),\n",
" description='Months (2015)',\n",
" disabled=False\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### ToggleButtons"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"widgets.ToggleButtons(\n",
" options=['Slow', 'Regular', 'Fast'],\n",
" description='Speed:',\n",
" disabled=False,\n",
" button_style='', # 'success', 'info', 'warning', 'danger' or ''\n",
" tooltips=['Description of slow', 'Description of regular', 'Description of fast'],\n",
"# icons=['check'] * 3\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### SelectMultiple\n",
"Multiple values can be selected with <kbd>shift</kbd> and/or <kbd>ctrl</kbd> (or <kbd>command</kbd>) pressed and mouse clicks or arrow keys."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"widgets.SelectMultiple(\n",
" options=['Apples', 'Oranges', 'Pears'],\n",
" value=['Oranges'],\n",
" #rows=10,\n",
" description='Fruits',\n",
" disabled=False\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## String widgets"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"There are several widgets that can be used to display a string value. The `Text`, `Textarea`, and `Combobox` widgets accept input. The `HTML` and `HTMLMath` widgets display a string as HTML (`HTMLMath` also renders math). The `Label` widget can be used to construct a custom control label."
" button_style='', # 'success', 'info', 'warning', 'danger' or ''\n",
" tooltip='Click me',\n",
" icon='check' # (FontAwesome names without the `fa-` prefix)\n",
")\n",
"button"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The `icon` attribute can be used to define an icon; see the [fontawesome](https://fontawesome.com/icons) page for available icons. \n",
"A callback function `foo` can be registered using `button.on_click(foo)`. The function `foo` will be called when the button is clicked with the button instance as its single argument."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Output\n",
"\n",
"The `Output` widget can capture and display stdout, stderr and [rich output generated by IPython](http://ipython.readthedocs.io/en/stable/api/generated/IPython.display.html#module-IPython.display). For detailed documentation, see the [output widget examples](https://ipywidgets.readthedocs.io/en/latest/examples/Output Widget.html)."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Play (Animation) widget"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The `Play` widget is useful to perform animations by iterating on a sequence of integers with a certain speed. The value of the slider below is linked to the player."
"The date picker widget works in Chrome, Firefox and IE Edge, but does not currently work in Safari because it does not support the HTML date input field."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"widgets.DatePicker(\n",
" description='Pick a Date',\n",
" disabled=False\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Color picker"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"widgets.ColorPicker(\n",
" concise=False,\n",
" description='Pick a color',\n",
" value='blue',\n",
" disabled=False\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## File Upload\n",
"\n",
"The `FileUpload` allows to upload any type of file(s) into memory in the kernel."
"The upload widget exposes a `value` attribute that contains the files uploaded. The value attribute is a tuple with a dictionary for each uploaded file. For instance:\n",
"\n",
"```python\n",
"uploader = widgets.FileUpload()\n",
"display(uploader)\n",
"\n",
"# upload something...\n",
"\n",
"# once a file is uploaded, use the `.value` attribute to retrieve the content:\n",
"Entries in the dictionary can be accessed either as items, as one would any dictionary, or as attributes:\n",
"\n",
"```\n",
"uploaded_file = uploader.value[0]\n",
"uploaded_file[\"size\"]\n",
"#=> 36\n",
"uploaded_file.size\n",
"#=> 36\n",
"```\n",
"\n",
"The contents of the file uploaded are in the value of the `content` key. They are a [memory view](https://docs.python.org/3/library/stdtypes.html#memory-views):\n",
"\n",
"```python\n",
"uploaded_file.content\n",
"#=> <memory at 0x10c1b37c8>\n",
"```\n",
"\n",
"You can extract the content to bytes:\n",
"\n",
"```python\n",
"uploaded_file.content.tobytes()\n",
"#=> b'This is the content of example.txt.\\n'\n",
"```\n",
"\n",
"If the file is a text file, you can get the contents as a string by [decoding it](https://docs.python.org/3/library/codecs.html):\n",
"The `FileUpload` changed significantly in ipywidgets 8:\n",
" \n",
"- The `.value` traitlet is now a list of dictionaries, rather than a dictionary mapping the uploaded name to the content. To retrieve the original form, use `{f[\"name\"]: f.content.tobytes() for f in uploader.value}`.\n",
"- The `.data` traitlet has been removed. To retrieve it, use `[f.content.tobytes() for f in uploader.value]`.\n",
"- The `.metadata` traitlet has been removed. To retrieve it, use `[{k: v for k, v in f.items() if k != \"content\"} for f in w.value]`.\n",
"</div>\n",
"\n",
"<div class=\"alert alert-warning\">\n",
"Warning: When using the `FileUpload` Widget, uploaded file content might be saved in the notebook if widget state is saved.\n",
"</div>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Controller\n",
"\n",
"The `Controller` allows a game controller to be used as an input device."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"widgets.Controller(\n",
" index=0,\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Container/Layout widgets\n",
"\n",
"These widgets are used to hold other widgets, called children. Each has a `children` property that may be set either when the widget is created or later."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Box"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"items = [widgets.Label(str(i)) for i in range(4)]\n",
"widgets.Box(items)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### HBox"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"items = [widgets.Label(str(i)) for i in range(4)]\n",
"widgets.HBox(items)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### VBox"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"items = [widgets.Label(str(i)) for i in range(4)]\n",
"This box uses the HTML Grid specification to lay out its children in two dimensional grid. The example below lays out the 8 items inside in 3 columns and as many rows as needed to accommodate the items."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"items = [widgets.Label(str(i)) for i in range(8)]\n",
"children = [widgets.Text(description=name) for name in tab_contents]\n",
"tab = widgets.Tab()\n",
"tab.children = children\n",
"tab.titles = [str(i) for i in range(len(children))]\n",
"tab"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Stacked\n",
"\n",
"The `Stacked` widget can have multiple children widgets as for `Tab` and `Accordion`, but only shows one at a time depending on the value of ``selected_index``:"
"### Accordion, Tab, and Stacked use `selected_index`, not value\n",
"\n",
"Unlike the rest of the widgets discussed earlier, the container widgets `Accordion` and `Tab` update their `selected_index` attribute when the user changes which accordion or tab is selected. That means that you can both see what the user is doing *and* programmatically set what the user sees by setting the value of `selected_index`.\n",
"\n",
"Setting `selected_index = None` closes all of the accordions or deselects all tabs."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In the cells below try displaying or setting the `selected_index` of the `tab` and/or `accordion`."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"tab.selected_index = 3"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"accordion.selected_index = None"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Nesting tabs and accordions\n",
"\n",
"Tabs and accordions can be nested as deeply as you want. If you have a few minutes, try nesting a few accordions or putting an accordion inside a tab or a tab inside an accordion. \n",
"\n",
"The example below makes a couple of tabs with an accordion children in one of them"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"tab_nest = widgets.Tab()\n",
"tab_nest.children = [accordion, accordion]\n",
"tab_nest.titles = ('An accordion', 'Copy of the accordion')\n",
"<interactive>:1:2: error: Not in scope: data constructor ‘StyleWidget’"
]
"data": {
"text/plain": []
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"s <- mkProgressStyle\n",
"setField s BarColor $ Just \"#ffff00\"\n",
"setField intProgress Style (StyleWidget s)"
]
},
{
"cell_type": "markdown",
"id": "b47fbb20-5c0a-4124-84fd-d06f2a10b635",
"metadata": {},
"source": [
"If a numerical text box imposes some kind of limit on the input (range, non-float, etc), that restriction is checked when the user presses enter or changes focus\n",
"There are several widgets that can be used to display single selection lists, and two that can be used to select multiple values. All inherit from the same base class. You can specify the **enumeration of selectable options** by passing a list of options labels.\n",
"\n",
"The selected index is specified with the field `OptionalIndex` in case it can be `Nothing` and `Index` if it's not a Maybe.\n",
"The `Password` widget hides user input on the screen. Nevertheless, this widget is **not a secure way** to collect sensitive information **because**:\n",
"- The contents are transmitted unencrypted\n",
"- If you save the notebook, the contents are stored as plain text"
"This box uses the HTML Grid specification to create a two-dimensional grid. To set its grid values, we need to create a layout widget. Let's do a 3x3 grid:"
" setField l StringValue $ pack $ (\"Label #\" ++ show i)\n",
" return $ ChildWidget l\n",
" \n",
"layout <- mkLayout\n",
"setField layout L.GridTemplateColumns $ Just \"repeat(3, 10em)\"\n",
" \n",
"gridBox <- mkGridBox\n",
"setField gridBox Children labels\n",
"setField gridBox Layout layout\n",
"gridBox"
]
},
{
"cell_type": "markdown",
"id": "269dcfce-ff9d-4c7a-85d1-6814dc813fd3",
"metadata": {},
"source": [
"### Accordion\n",
"\n",
"Unlike the other container widgets, `Accordion` and `Tab` update their `selected_index` attribute when a tab or accordion element is selected. You can see what the user is doing, or set what the user is seeing.\n",
"\n",
"You can set `selected_index` to `Nothing` to close all accordions or deselect all tabs."
@@ -50,4 +50,36 @@ First you have to check if the attribute is only for one widget, or is from a co
> Some widgets receive messages from the frontend when a value is modified (such as sliders, text areas, buttons...). You'll have to modify the `comm` function instantiated from the class `IHaskellWidget`. You can find an example at [IntSlider.hs](./Int/BoundedInt/IntSlider.hs)
## FAQ
When using widgets in ihaskell, you'll encounter a lot of compilation errors. If you are not very familiar with Haskell, they can be a bit hard to decipher, this is a mini guide that will (hopefully) appear when you paste the error in Google.
\ No newline at end of file
When using widgets in ihaskell, you'll encounter a lot of compilation errors. If you are not very familiar with Haskell, they can be a bit hard to decipher, this is a mini guide that will (hopefully) appear when you paste the error in Google.
### setField: No instance for...
You probably got this error when trying to use setField like this: