Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Example of binding similar handler to many widgets #1680

Open
RDeRenzi opened this issue Aug 28, 2017 · 2 comments
Open

Example of binding similar handler to many widgets #1680

RDeRenzi opened this issue Aug 28, 2017 · 2 comments

Comments

@RDeRenzi
Copy link

I thought this example might be of use to others, since documentation is still (understandably) a weak point of ipywidgets. The title might be How to use a single handler for many equivalent widgets in a Box (e.g. input parameter guess values for a multi-parameter fit toolkit). Also the continuous_update example is missing in the docs. It took me quite some time to understand how to do both.

from ipywidgets import Text, HBox
t1=Text(description='t1',continuous_update=False)
t2=Text(description='t2',continuous_update=False)
result1,result2 = [],[]

def on_text(change):
       n=change['owner'].description
       exec('result'+n[1:]+'.append(change["new"])') # could be generalized for any name of the kind
      # [string+str(k) for k in range(kk)],  implying kk similarText widgets displayed in the page
      print('result1 = {}\nresult2 = {}'.format(result1,result2)) 
      # print('n = {}, change["new"] = {}'.format(n,change['new']))
t1.observe(on_text,'value',type= 'change')
t2.observe(on_text,'value',type= 'change')
h = HBox([t1,t2])
h

Sorry, perhaps it is not the best of codes, but it does what I intended.

@jasongrout jasongrout modified the milestone: Future Aug 28, 2017
@pbugnion
Copy link
Member

pbugnion commented Sep 2, 2017

Thanks for submitting this. Something like this could potentially go in the Traitlet events section of the Widget events documentation. Ultimately, someone with more experience dealing with user issues (e.g. @jasongrout ) should decide whether there is value in this going into the documentation.

Regardless of whether this is suitable for documentation, I think that there are a few things that could be improved with the snippet. I would avoid using exec as much as possible. Besides being unpythonic, it opens up security issues around code injection (though it doesn't look like this example suffers from them). See this for a discussion.

As I understand, you are trying to use exec to dispatch the change to the correct list. An alternative would be to pass the list as a second argument to on_text:

def on_text_change(change, list_to_change):
    list_to_change.append(change['new'])

You can then parametrize on_change using lambdas in your call to observe:

from ipywidgets import Text, HBox

t1 = Text(continuous_update=False)
t2 = Text(continuous_update=False)
result1, result2 = [], []

t1.observe(lambda change: on_text_change(change, result1), 'value', type='change')
t2.observe(lambda change: on_text_change(change, result2), 'value', type='change')

HBox([t1, t2])

As a further improvement, to avoid duplicating code and to make this more robust against possible future scope changes, you could use a loop across the number of widgets you want to make.

from ipywidgets import Text, HBox

NUMBER_WIDGETS = 3

def instantiate_widget(description):
    widget = Text(description=description, continuous_update=False)
    result = []
    widget.observe(lambda change: on_text_change(change, result), 'value', type='change')
    return widget, result

widgets = []
results = []

for iwidget in range(NUMBER_WIDGETS):
    widget, result = instantiate_widget(description=str(iwidget))
    widgets.append(widget)
    results.append(result)

HBox(widgets)

@pbugnion pbugnion changed the title one example (for docs) Example of binding similar handler to many widgets Sep 2, 2017
@jasongrout jasongrout added the docs label Sep 5, 2017
@jasongrout
Copy link
Member

Ultimately, someone with more experience dealing with user issues (e.g. @jasongrout ) should decide whether there is value in this going into the documentation.

+1 to adding some helpful section and more examples about registering handlers. Perhaps this could be a more complicated example, perhaps even showing how to do an interact-style dashboard manually.

I like @pbugnion's version above too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants