ipywidgets dropdown widgets: what is the onchange event?

45,935

Solution 1

Between this link and the traitlet docs on github and just playing around, I finally figured this out:

w = widgets.Dropdown(
    options=['Addition', 'Multiplication', 'Subtraction', 'Division'],
    value='Addition',
    description='Task:',
)

def on_change(change):
    if change['type'] == 'change' and change['name'] == 'value':
        print("changed to %s" % change['new'])

w.observe(on_change)

display(w)

Overall this looks a lot richer than the deprecated interface, but it could definitely use more examples.

Solution 2

You can specify the change name in observe. This makes for cleaner code, and the handler is not called for changes you don't need:

from IPython.display import display
from ipywidgets import Dropdown

def dropdown_eventhandler(change):
    print(change.new)

option_list = (1, 2, 3)
dropdown = Dropdown(description="Choose one:", options=option_list)
dropdown.observe(dropdown_eventhandler, names='value')
display(dropdown)

Solution 3

Put it all together

Inspired on previous answers and lambda expressions I use this:

def function(option):
    print(option)


w = widgets.Dropdown(
    options=['None', 'Option 1', 'Option 2', 'Option 3'],
    description='Option:',
    disabled=False
)

w.observe(
    lambda c: plot_content(c['new']) if (c['type'] == 'change' and c['name'] == 'value') else None
)

display(w)

Solution 4

I agree that event handling is not as thorough as would be desired: I have been filtering the events as you receive multiple events for a typical dropdown change as the index changes, the value changes, i.e., change['name'].

I am doing the following:

def on_dropdown_change(change):
    if change['name'] == 'value' and (change['new'] != change['old']):
        print('do something with the change')
dropdown =  ipywidgets.Dropdown({options=['one','two','three'],
                                 value='one'})
dropdown.observe(on_dropdown_change)

Solution 5

I believe the idea is to use trait name, e.g. value. For example:

from ipywidgets import Dropdown

def handle_change():
    print type_sel.value

type_sel = Dropdown(description="Keypoint type", options=['surf', 'orb'])
type_sel.on_trait_change(handle_change, name="value")
display(type_sel)

SciPy 2015 Advanced Jupyter Video Tutorial

Share:
45,935

Related videos on Youtube

Tim Richardson
Author by

Tim Richardson

Updated on July 09, 2022

Comments

  • Tim Richardson
    Tim Richardson almost 2 years

    I can register a handler to button.on_click in ipython notebook widgets, but I don't know how to do the same for a dropdown widget

    import ipywidgets as widgets
    from IPython.display import display
    
    def on_button_clicked(b):
        print("Button clicked.")
    
    button = widgets.Button(description="Click Me!")
    display(button)
    
    button.on_click(on_button_clicked)
    

    But for

    choose_task = widgets.Dropdown(
        options=['Addition', 'Multiplication', 'Subtraction'],
        value='Addition',
        description='Task:',
    )
    

    there seems to be only

    on_trait_change(...)
    

    if I register a handler with this, can I use it to access the value of the widget? I have seen examples with the handler and the widget belong to a subclass, and the handler can use self to introspect. But if I don't want to use a subclass, how does the handler know what widget was the target of the event.?

    • Brandon Kuczenski
      Brandon Kuczenski almost 8 years
      did you ever figure out your introspection question?
  • Brandon Kuczenski
    Brandon Kuczenski almost 8 years
    That is horribly documented
  • sfjac
    sfjac over 7 years
    Also, I get a warning when I try to use this: [...]/anaconda/lib/python2.7/site-packages/ipykernel/__main_‌​_.py:13: DeprecationWarning: on_trait_change is deprecated in traitlets 4.1: use observe instead but when I try using observe my handler is called three times.
  • CodingMatters
    CodingMatters about 6 years
    Thanks for this. I've been looking for methods/examples to combine multiple widgets into selecting values for a function, slicing/dicing data, selecting type of plots from data etc.
  • fabiob
    fabiob about 4 years
    any idea how to make the widget disappear/become inactive after one value has been selected?
  • fabiob
    fabiob about 4 years
    I am actually looking for a widget with two buttons. Clicking on one action A is performed, clicking on the other one action B is performed.
  • fabiob
    fabiob about 4 years
    any idea what to do if we want to pass an argument to the on_change function?
  • alex
    alex over 3 years
    @fabiob use functools.partial: github.com/jupyter-widgets/ipywidgets/issues/…
  • ReinholdN
    ReinholdN about 3 years
    @sfjac how would I convert the return from the dropdown into a str to filter a dataframe and pandas, such as: selection = change['new'] df[df['column' == selection]]
  • jax
    jax almost 3 years
    is there any solution for this? stackoverflow.com/questions/67927358/…
  • jax
    jax almost 3 years
    is there any solution for this? stackoverflow.com/questions/67927358/…
  • jax
    jax almost 3 years
    is there any solution for this? stackoverflow.com/questions/67927358/…
  • gokul_uf
    gokul_uf almost 3 years
    @fabiob try change.owner.disabled = True inside the handler