Hugo
Hugo

Reputation: 567

kivy - custom form in a scrollview

Say I have a custom slider form like in this template here:

<SliderForm@BoxLayout>:
    orientation: 'vertical'
    padding: [0, '5 dp']
    size_hint_y: None

    form_title: "Slider"
    slider_value: slider_widget.value
    slider_max: slider_widget.max

    Label:
        text: root.form_title
        bold: True
        text_size: (self.width - 20, self.height)
        halign: 'left'

    BoxLayout:
        Slider:
            id: slider_widget
            min: 1
            max: 5
            value: 1
            step: 1
            padding: '15 dp'

        Label:
            text: str(int(root.slider_value))
            size_hint_x: None
            width: self.height

Now I need to have multiple of these and was thinking of placing them inside a scrollview, but I can't figure how to.

My attempt is:

<MyScreen>:
    BoxLayout:
        orientation: "vertical"

        ScrollView:
            BoxLayout:
                orientation: "vertical"
                size_hint_y: None
                minimum_height: self.setter('height')

                SliderForm:
                    form_title: "Amount"

                SliderForm:
                    form_title: "Other"

This way, the forms are never well positioned... Either they are missing or stacked on top of each other.

Upvotes: 0

Views: 162

Answers (2)

S0AndS0
S0AndS0

Reputation: 920

Here's two more options on making layouts ScrollView friendly.

class Scrollable_GridLayout(GridLayout):
    def __init__(self, **kwargs):
        super(Scrollable_GridLayout, self).__init__(**kwargs)
        self.size_hint_y: None
        self.bind(minimum_height = self.setter('height'))

Option one (above), set a class that inherits from the desired layout and set self.bind(minimum_height = self.setter('height')), option two (bellow), set the height based off summed children heights.

<Scrolling_GridLayout@GridLayout>:
    size_hint_y: None
    height: sum([c.height for c in self.children])

Upvotes: 0

inclement
inclement

Reputation: 29488

BoxLayout:
    minimum_height: self.setter('height')

This isn't right. First, BoxLayout doesn't have a minimum_height property, so you're just creating a new one that doesn't do anything. Second, self.setter('height') returns a function, but you don't call it or anything so that also does nothing.

It seems like maybe you really mean:

GridLayout:
    size_hint_y: None
    height: self.minimum_height

GridLayout does have a minimum_height property that sums the height of its children, so this will make its size adjust dynamically. This is a normal way to work with a ScrollView.

However, this isn't the only thing wrong. Your SliderForm includes size_hint_y: None but doesn't actually set its height anywhere, so it will have the default of 100 pixels. Maybe you meant to set some fixed value, e.g. height: 600?

Upvotes: 1

Related Questions