question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

widget composition in pure python

See original GitHub issue

I 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:closed
  • Created 3 years ago
  • Comments:15 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
jasongroutcommented, Apr 8, 2020

Hopefully in the next few months

1reaction
bendichtercommented, Apr 8, 2020

yes, thanks to both of you.

Now that we have a value attribute, here’s a version that’s a bit cleaner:

from ipywidgets import HBox, FloatRangeSlider, Button, ValueWidget, link, interact
from ipywidgets.widgets.widget_description import DescriptionWidget

class MyWidget(HBox, ValueWidget, DescriptionWidget):
    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]
        link((self.slider, 'value'), (self, 'value'))
        link((self.slider, 'description'), (self, 'description'))
        
    def move_up(self, change):
        self.value = (self.value[0] + 1, self.value[1] + 1)

        
my_widget = MyWidget()
my_widget.observe(lambda x: print(x))
my_widget
Read more comments on GitHub >

github_iconTop Results From Across the Web

Building Reusable User Interface Components
This is not a scalable solution, in that writing custom widgets can only be performed using pure PyGTK, rather than GtkBuilder files.
Read more >
4 12 Composition vs Inheritance Building Flutter Widgets From ...
Composition vs Inheritance Building Flutter Widgets From ScratchInheritance and polymorphism in FlutterThe Flutter UI framework, ...
Read more >
tkinter.ttk — Tk themed widgets — Python 3.11.1 documentation
The tkinter.ttk module provides access to the Tk themed widget set, ... under X11 and window transparency (requiring a composition window manager on...
Read more >
QOpenGLWidget — Qt for Python - Qt Documentation
As described above, subclass QOpenGLWidget to render pure 3D content in the ... Instead, it is up to the widget stack to manage...
Read more >
Composition in Flutter & Dart [Functional Programming — Part 3]
Flutter heavily uses composition. The Widget tree which we deal with to design our UIs follows composition. Widgets are like Lego bricks.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found