widget composition in pure python
See original GitHub issueI am loving this library, great work devs! I’m hoping you could help me work out a snag I’m facing.
I would like to create widgets that are compositions of other widgets and that have their own observe
method. I’d like to do this in pure python if I can, and I think I am very close. What I have now is:
from ipywidgets import HBox, FloatRangeSlider, Button
class MyWidget(HBox):
def __init__(self):
super(MyWidget, self).__init__()
self.slider = FloatRangeSlider()
self.button = Button(description='next')
self.button.on_click(self.move_up)
self.children = [self.slider, self.button]
def move_up(self, change):
value = self.slider.value
self.slider.set_state({'value': (value[0] + 1, value[1] + 1)})
my_widget = MyWidget()
my_widget.observe = my_widget.slider.observe
my_widget.observe(lambda x: print(x))
my_widget
This achieves the desired result, but the problem with my current solution is that I have to add the observe
method on an instance of the MyWidget
class rather than putting this somehow in the MyWidget
class definition. I have tried variants of
class MyWidget(HBox):
def __init__(self):
super(MyWidget, self).__init__()
self.slider = FloatRangeSlider()
self.button = Button(description='next')
self.button.on_click(self.move_up)
self.children = [self.slider, self.button]
def move_up(self, change):
value = self.slider.value
self.slider.set_state({'value': (value[0] + 1, value[1] + 1)})
def observe(self, handler, **kwargs):
self.slider.observe(handler, **kwargs)
my_widget = MyWidget()
but I haven’t gotten anything to work. The error I get from the above is:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-62-3ea00d238837> in <module>
17 self.slider.observe(handler)
18
---> 19 my_widget = MyWidget()
~/opt/anaconda3/lib/python3.7/site-packages/traitlets/traitlets.py in __new__(cls, *args, **kwargs)
956 else:
957 inst = new_meth(cls, *args, **kwargs)
--> 958 inst.setup_instance(*args, **kwargs)
959 return inst
960
~/opt/anaconda3/lib/python3.7/site-packages/traitlets/traitlets.py in setup_instance(self, *args, **kwargs)
984 self._trait_notifiers = {}
985 self._trait_validators = {}
--> 986 super(HasTraits, self).setup_instance(*args, **kwargs)
987
988 def __init__(self, *args, **kwargs):
~/opt/anaconda3/lib/python3.7/site-packages/traitlets/traitlets.py in setup_instance(self, *args, **kwargs)
975 else:
976 if isinstance(value, BaseDescriptor):
--> 977 value.instance_init(self)
978
979
~/opt/anaconda3/lib/python3.7/site-packages/traitlets/traitlets.py in instance_init(self, inst)
922
923 def instance_init(self, inst):
--> 924 inst.observe(self, self.trait_names, type=self.type)
925
926
TypeError: observe() takes 2 positional arguments but 3 were given
Has anyone done something like this? Any tips on how I might get this to work as intended? I think pure python “widget composition” capability could be really useful for lots of users.
This is very similar to #700, in which @jasongrout suggested this would be possible in pure python. @pbugnion this seems up your alley as well as it is similar to #1543.
Issue Analytics
- State:
- Created 3 years ago
- Comments:15 (5 by maintainers)
Hopefully in the next few months
yes, thanks to both of you.
Now that we have a
value
attribute, here’s a version that’s a bit cleaner: