Search code examples
python-3.xkivykivy-languagekivymd

Center a Label vertically within a GridLayout's row in Kivy/KivyMD


I am new to Kivy/KivyMD. I am trying to create a Scrollable GridLayout, which will be used to show verses. I specifically want to use a 2 column GridLayout. (1 column for English verses and the 2nd column for the same verses regionally translated)

I have got the basic structure going, but for the life of me cannot figure out how to align the row items to the top or center. By default it aligns the row items to the bottom of the row. (As in the figure)

enter image description here

How can I align my verses (the row items), such that they are top aligned?

My KV file:

<VerseItem@MDLabel>
text: "1. I am a verse. I need to be top aligned with my sibling\n"*5
adaptive_height: True
md_bg_color: "blue"

<VerseItem2@MDLabel>
    md_bg_color: "red"
    text: "2 I am a Totally different verse, I need to be top aligned with my sibling"
    adaptive_height: True

<ScratchLayout>
    orientation:'vertical'
    ScrollView:
        do_scroll_y: True
        MDGridLayout:
            padding: "10dp"
            spacing: "20dp"
            height: self.minimum_height
            cols:2
            size_hint_y: None
            VerseItem:
            VerseItem2:
            VerseItem:
                text:"The text can change, but must be top aligned"
            VerseItem2:
                text: "Hello, world"*10
            VerseItem:
                text: "Hello, world"*4
            VerseItem2:
                text: "Hello, world"*15
            VerseItem:
            VerseItem2:
            VerseItem:
                text:"The text can change, but must be top aligned"
            VerseItem2:
                text: "Hello, world"*10
            VerseItem:
                text: "Hello, world"*4
            VerseItem2:
                text: "Hello, world"*15

My python file:

from kivymd.app import MDApp
from kivymd.uix.boxlayout import MDBoxLayout

class ScratchLayout(MDBoxLayout):
    pass

class Example(MDApp):

    def build(self):
        self.theme_cls.theme_style = "Dark"
        self.theme_cls.primary_palette = "Orange"
        return ScratchLayout()


Example().run()

Solution

  • Rather than using an MDGridLayout with 2 columns, just use one column. Then use a widget for each row in the MDGridLayout. Here is a modified version of your kv file that does that:

    <VerseRow@MDBoxLayout>:
        adaptive_height: True
        text1: "1. I am a verse. I need to be top aligned with my sibling\n"*5
        text2: "2 I am a Totally different verse, I need to be top aligned with my sibling"
        MDLabel:
            text: root.text1
            adaptive_height: True
            md_bg_color: "blue"
            pos_hint: {'top': 1}
        MDLabel:
            text: root.text2
            md_bg_color: "red"
            adaptive_height: True
            pos_hint: {'top': 1}
    
    
    <ScratchLayout>
        orientation:'vertical'
        ScrollView:
            do_scroll_y: True
            MDGridLayout:
                id: grid
                padding: "10dp"
                spacing: "20dp"
                height: self.minimum_height
                size_hint_y: None
                cols:1
                VerseRow:
                VerseRow:
                    text1: "The text can change, but must be top aligned"
                    text2: "Hello, world"*10
                VerseRow:
                    text1: "Hello, world"*4
                    text2: "Hello, world"*15
                VerseRow:
                VerseRow:
                    text1: "The text can change, but must be top aligned"
                    text2: "Hello, world"*10
                VerseRow:
                    text1: "Hello, world"*4
                    text2: "Hello, world"*15