Search code examples
user-interfacebuttonresizekivydefault

How do I add a small button to a ScatterLayout in Kivy? Label works auto, Button does not


from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.scatterlayout import ScatterLayout

class ZoomWidget(ScatterLayout):
    def __init__(self, **kwargs):
        super(ZoomWidget, self).__init__(**kwargs)
        self.add_widget(Label(text='Label'))

    def on_touch_down(self, touch):
        if touch.is_double_tap:
            button = Button(text='Button')
            self.add_widget(button) 
            return True
        else:
            return super().on_touch_down(touch)


class ZoomSpaceApp(App):
    def build(self):
        return ZoomWidget()


if __name__ == '__main__':
    ZoomSpaceApp().run()

So, the label seems to work, I can right-click (on desktop OS) to create a second touch location, then left dragging scales & rotates the label. However, the button just seems to fill up the whole layout, and I can't scale or rotate it. So how do I get the Button to act as the Label does by default, within a ScatterLayout?

Also, I want to do something similar using other widgets, so the most general answer will do. For example, do I encapsulate the Button in some type of widget such as a layout? What shows up in the ZoomWidget will be other widgets. The point of my application is for the user to create their own apps by touches and decide what to put there (with a context menu at first). Knowing that, is there a better way to approach this?


Solution

  • It doesn't work, because Button works with touches too, therefore it'll most likely eat all your touches and won't let anything for ScatterLayout to work with. To get it work you need to have an area that belongs to ScatterLayout alone a user can work with.

    As Label doesn't work with touches as Button does, it passes the touch to the first widget it can use it i.e. in this case the ScatterLayout.

    def on_touch_down(self, touch):
        if touch.is_double_tap:
            button = Button(text='Button', size_hint=(0.9, 0.9))
            self.add_widget(button)
            return True
        else:
            return super(ZoomWidget, self).on_touch_down(touch)