I'm experimenting with Jupyter Widgets to see if I can make a better version of this, but apparently the observe handler triggers even when the change is not from the user, so it creates an infinite loop of one widget changing the other. Minimal example:
import ipywidgets as widgets
a = widgets.FloatText(description='a:')
b = widgets.FloatText(description='b:')
def on_a_change(change):
b.value = change['new'] + 1
a.observe(on_a_change, names='value')
def on_b_change(change):
a.value = change['new'] + 1
b.observe(on_b_change, names='value')
display(a)
display(b)
Is there any way to only trigger on a user-initiated change? In other words, the user updates one text box, and then the others are updated from it, but those updates don't trigger more updates.
Not sure if I understood the requirement, but if it is "update one more than other", then you can try the following
import ipywidgets as widgets
a = widgets.FloatText(description='a:')
b = widgets.FloatText(description='b:')
def update_one(x):
return x + 1
widgets.link((a, 'value'), (b, 'value'), (update_one, update_one))
display(a)
display(b)
widgets.link
seems to do the trick, if you do widgets.link.__doc__
you can see the docs and it accepts a third parameter.
>>> print(widgets.link.__doc__)
Link traits from different objects together so they remain in sync.
Parameters
----------
source : (object / attribute name) pair
target : (object / attribute name) pair
transform: iterable with two callables (optional)
Data transformation between source and target and target and source.
So I have added an iterable of callables and made it return 1
more than your entered value.