ForyszeP
ForyszeP

Reputation: 163

Kivy. Position of GridLayout inside ScrollView

I give up. I think I have tried everything I possibly could. I need some explatanion how to position nested layouts classes. In below code I need these labels to be positioned in the center of the screen. Anything I've tried leaves the Labels on the left side.

from kivy.app import App
from kivy.lang import Builder

kv = """

<StorageLabel@Label>
    background_normal: ''
    size_hint: None, None
    size: 65, 50
    canvas.before:
        Color:
            rgba: (1, 0, 0.5, 1) 
        Rectangle:
            pos: self.pos
            size: self.size
    halign: "left"
    valign: "middle"    

<Storage@BoxLayout>
    ScrollView:
        size_hint_x: 1
        bar_width: 10
        scroll_type: ['bars', 'content']
        bar_color: [0, 0, 0, 1]
        bar_inactive_color: [0, 0, 0, 1]
        pos_hint: {'center_x': 0.5}
        GridLayout:

            cols: 3
            size_hint_y: None
            size: self.minimum_size
            height: self.minimum_height

            StorageLabel:
                text: '1m'

            StorageLabel:
                text: '2m'

            StorageLabel:
                text: '3m'

Storage:

"""

sm = Builder.load_string(kv)

class Main(App):
    def build(self):
        return sm

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

Upvotes: 0

Views: 165

Answers (1)

John Anderson
John Anderson

Reputation: 38937

The easiest way to center the Labels is to let the GridLayout size and position them. This results in a larger width for each Label, but they are centered:

from kivy.app import App
from kivy.lang import Builder

kv = """

<StorageLabel@Label>
    background_normal: ''
    # leave size_hint_x at default of 1
    size_hint_y: None
    height: 50
    canvas.before:
        Color:
            rgba: (1, 0, 0.5, 1) 
        Rectangle:
            pos: self.pos
            size: self.size

<Storage@BoxLayout>
    ScrollView:
        size_hint_x: 1
        bar_width: 10
        scroll_type: ['bars', 'content']
        bar_color: [0, 0, 0, 1]
        bar_inactive_color: [0, 0, 0, 1]
        pos_hint: {'center_x': 0.5}
        GridLayout:
            cols: 3
            # add some padding and spacing
            padding: 5
            spacing: 5
            size_hint_y: None
            height: self.minimum_height

            StorageLabel:
                text: '1m'

            StorageLabel:
                text: '2m'

            StorageLabel:
                text: '3m'

Storage:

"""

sm = Builder.load_string(kv)

class Main(App):
    def build(self):
        return sm

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

If you want the labels to be your original size, then you can place each in its own Layout (perhaps a FloatLayout), and let the GridLayout size and position those Layouts:

from kivy.app import App
from kivy.lang import Builder

kv = """

<StorageLabel@Label>
    background_normal: ''
    size_hint: None, None
    size: 65, 50
    # position the label in the center of its FloatLayout
    pos_hint: {'center_x':0.5}
    canvas.before:
        Color:
            rgba: (1, 0, 0.5, 1) 
        Rectangle:
            pos: self.pos
            size: self.size

<Storage@BoxLayout>
    ScrollView:
        size_hint_x: 1
        bar_width: 10
        scroll_type: ['bars', 'content']
        bar_color: [0, 0, 0, 1]
        bar_inactive_color: [0, 0, 0, 1]
        pos_hint: {'center_x': 0.5}
        GridLayout:
            cols: 3
            size_hint_y: None
            height: self.minimum_height
            # set the default row height to the height of the Labels
            row_default_height: 50

            FloatLayout:
                StorageLabel:
                    text: '1m'

            FloatLayout:
                StorageLabel:
                    text: '2m'

            FloatLayout:
                StorageLabel:
                    text: '3m'

Storage:

"""

sm = Builder.load_string(kv)

class Main(App):
    def build(self):
        return sm

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

Upvotes: 1

Related Questions