Eric MacLeod
Eric MacLeod

Reputation: 461

Usig Kivy how can I generate scaled buttons in a scrollview

I'm pretty new to kivy and I'm having some trouble with sizing and positioning the widgets, I'm trying to generate buttons that will be in a gridlayout inside a scrollview. When I press the button in the lower right corner I want to generate some buttons scaled to the width of that button.

Before the button is pressed

But this is how the buttons turn out

After button is pressed

class RootWidget(BoxLayout):
    pass

class CustomLayout(FloatLayout):

    def __init__(self, **kwargs):
        # make sure we aren't overriding any important functionality
        super(CustomLayout, self).__init__(**kwargs)

        with self.canvas.before:
            Color(0, 1, 0, 1)  # green; colors range from 0-1 instead of 0-255
            self.rect = Rectangle(size=self.size, pos=self.pos)

        self.bind(size=self._update_rect, pos=self._update_rect)

    def _update_rect(self, instance, value):
        self.rect.pos = instance.pos
        self.rect.size = instance.size

class MainApp(App):

    def build(self):
        root = RootWidget()
        c = CustomLayout()
        root.add_widget(c)

        def on_enter(self):
            func = Function()
            buttons = func.buttons()
            root.add_widget(buttons)

        get_buttons = Button(
            text='Get links',
            size_hint=(.5, .10),
            pos=(20, 20))
        root.add_widget(get_buttons)

        get_buttons.bind(on_press=on_enter)
        return root

class Function:
    def buttons(self):
        layout = GridLayout(cols=1, padding=1, spacing=10,
                size_hint=(None, None), width=20)

        layout.bind(minimum_height=layout.setter('height'))
        for buttn in range(20):
            btn = Button(text='test', size=(20, 50),
                         size_hint=(None, None))
            layout.add_widget(btn)
        # create a scroll view, with a size < size of the grid
        root = ScrollView(size_hint=(None, None), size=(20, 500),
                pos_hint={'center_x': .5, 'center_y': .5}, do_scroll_x=False)

        root.add_widget(layout)
    return root

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

Upvotes: 1

Views: 1150

Answers (1)

jligeza
jligeza

Reputation: 4693

I strongly recommend you using kv file to describe GUI, because it's much easier to read, and therefore maintain. Look at this example:

test.kv:

#:kivy 1.9.0
GridLayout:
    rows: 1

    LeftArea:
    RightArea:


<LeftArea@FloatLayout>:

    canvas:
        Color:
            rgb: 0, 1, 0
        Rectangle:
            size: self.size
            pos: self.pos


<RightArea@GridLayout>:
    cols: 1
    size_hint_x: 0.3
    spacing: '10dp'

    ScrollView:
        LinksGrid:
            id: links_grid

    GetLinksButton:
        links_grid: links_grid


<LinksGrid@GridLayout>:
    cols: 1
    spacing: '5dp'
    size_hint_y: None
    height: self.minimum_height


<GetLinksButton>:
    size_hint_y: 0.2
    text: 'get links'
    on_press: self.get_links()


<LinkButton>:
    size_hint_y: None
    height: '80dp'

main.py:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from kivy.app import App
from kivy.uix.button import Button


class GetLinksButton(Button):

    link_number = 1

    def get_links(self):
        for i in xrange(3):
            link_button = LinkButton(
                text='link number ' + str(self.link_number)
            )
            self.link_number += 1
            self.links_grid.add_widget(link_button)


class LinkButton(Button):
    pass


class Test(App):
    pass


Test().run()

Result:

enter image description here

Upvotes: 3

Related Questions