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)
 

Top Related StackOverflow Question
Hopefully in the next few months
yes, thanks to both of you.
Now that we have a
valueattribute, here’s a version that’s a bit cleaner: