Alf
Alf

Reputation: 1989

Linking ipython widget dropdown and slider values

I "understand" how to link a text box to a slider (by "understand" I mean how to make it work):

from traitlets import link

a = widgets.FloatText(value=4.)
b = widgets.FloatSlider(min=3,max=7,step=0.23,value=4.)
display(a,b)

mylink = link((a, 'value'), (b, 'value'))

This results in something like this:

linking widgets

But is there any way how I can link a dropdown box, whose values would be list_items = ('case1', 'case2', 'case3') to the FloatSlider, where the corresponding values would be e.g. (3.4, 5.4, 6.7) ?

Upvotes: 1

Views: 3141

Answers (1)

rmenegaux
rmenegaux

Reputation: 176

Yes you can.

Using directional_link

The link functionality ties together two traits of the same type. If you need to apply a transformation on one of the traits, you should use directional_link:

from ipywidgets import Dropdown, FloatSlider
from traitlets import directional_link
from IPython.display import display

a= Dropdown(options=['case1', 'case2', 'case3'])
b= FloatSlider(min=3, max=7, step=0.23, value=4)

def transform(case):
    return {'case1': 3.4, 'case2': 5.4, 'case3': 6.7}[case]

directional_link((a, 'value'), (b, 'value'), transform)

display(a, b)

Note that this only goes one way, a --> b, so updating the dropdown updates the slider, but not the other way around. If you want the linking to go both ways, you have to use another directional_link:

directional_link((b, 'value'), (a, 'value'), inverse_transform)

Using observe

observe is the standard way to listen for a trait change in widgets. This is the way to go if you want to trigger more complicated behavior than just linking two traits.

In your example:

def update_slider(change):
    b.value = {'case1': 3.4, 'case2': 5.4, 'case3': 6.7}[a.value]

a.observe(update_slider, names='value')

Once again, this goes one way (a --> b) only. Observe changes in b to make the linking bi-directional

Upvotes: 6

Related Questions