Search code examples
pythonpositionkivy

Python Kivy Position


I've been using Python to work on large excel files for some time now. Functionally, it works.

In order for other people to use it, i need to develop a simple interface where I show check boxes or radio buttons. Everything is working but i'm having trouble with the aesthetics of the whole thing.

I'm using 6 tabs, inside each tab there are a series of options. The .kv file below shows the tab configuration and the first tab.

<Test>:
    size_hint: 1, 1
    pos_hint: {'center_x': .5, 'center_y': .5}
    do_default_tab: False
    tab_width: root.width / 6
    tab_height: 50


    TabbedPanelItem:
        text: 'References'
        BoxLayout:
            size_hint: (1, 1)
            height:160
            #pos_hint: {'top': 0.5, 'x': 0}
            orientation: 'vertical'
            text_size: self.size
            #valign: "left"
            padding_x: 10


            BoxLayout:
                #size_hint: (0.35, 0.2)
                height:20
                pos_hint: {'x': 0}
                text_size: self.size                
                padding_x: 5


                CheckBox:
                    on_active: root.ref_caracEspe(self, self.active)
                    active: True
                    pos_hint: {'x': 0, 'y': 0}



                Label:
                    text: 'RCE'
                    #pos_hint: {'x': 0, 'y': 0}


            BoxLayout:
                #size_hint: (0.35, 0.2)
                height:20
                pos_hint: {'x': 0}
                text_size: self.size                
                padding_x: 5

                CheckBox:

                    on_active: root.ref_allowUnder(self, self.active)



                Label:
                    text: 'Allow "_"'
                    valign: "top"

            BoxLayout:
                #size_hint: (1, 0.2)
                height:20
                #pos_hint: {'x': 0}
                pos_hint: {'center_x': .33, 'center_y': .0}
                text_size: self.size                
                #padding_x: 5   

                CheckBox:
                    on_active: root.ref_spaces(self, self.active)
                    active: True
                    pos_hint: {'x': 1, 'y': 0}


                Label:
                    text: 'RSP'
                    valign: "top"
                    #pos_hint: {'x': 0.3, 'y': 0}


            BoxLayout:
                #size_hint: (0.35, 0.2)
                height:20
                pos_hint: {'x': 0}
                text_size: self.size                
                padding_x: 5


                CheckBox:
                    on_active: root.ref_max15(self, self.active)
                    active: True             


                Label:
                    text: 'Max: 15'
                    valign: "top"
                    pos_hint: {'x': 0.5, 'y': 0}

I need the check boxes / radio buttons to be to right where the window starts (x=0?) and the text very close to the checkbox. I managed to get the checkbox to the x edge, but the text keeps getting spaced.

Spaced label

I tried different things with not a lot of success. Thanks for your time!


Solution

  • You gather each CheckBox and Label pair in their own BoxLayout, which is a good practice imho. One point is that BoxLayout distribute it's space equally between its children, if not specified by their size properties (size, width, size_hint, size_hint_x (and height, size_hint_y if BoxLayout's orientation property is set to 'vertical')).

    The other point is that the Label's text takes only the size it needs by default, not the entire Label size.

    By default, the size of Label is not affected by text content and the text is not affected by the size. In order to control sizing, you must specify text_size to constrain the text and/or bind size to texture_size to grow with the text.

    So in your case you can try with

    BoxLayout:
        orientation: 'horizontal'    #default anyway
        CheckBox:
            active: True
            size_hint_x: 0.1
        Label:
        text_size: self.size
        text: 'Check!'
        valign: 'center'      #The default is 'bottom'
        halign: 'left'        #default anyway
    

    or even better:

    BoxLayout:                
        CheckBox:
            active: True
            size_hint_x: None   #
            width: 30           # in pixels
        Label:
        text_size: (self.width, None)
        text: 'Check!'
    

    fine-tune the CheckBox's width to the width of its image (you can go ahead to get its real size from its properties, but it could go hacky since it only keep StringProperties of it's images) size_hint_x is set to None so that the parent layout (BoxLayout) don't look for a relative width (which defaults to 1, the wider possible), and second to fixed width.

    The BoxLayout will first assign The CheckBox to its location and size, since it specify a desired size, then use all the left space for the Label.

    And for the Label part, in the first example, its text_size is set to all the size of the Label, so the alignment was respected even for a single word. The vertical alignment valign is set to center to be on the same alignment as the checkbox, instead being on the bottom like the default. In the second example, only the first item of text_size (its width) was set to Label's width, so the height of the text won't exceed it's actual height, thus the valign isn't needed anymore.

    ref: 1- https://kivy.org/docs/api-kivy.uix.boxlayout.html 2- https://kivy.org/docs/api-kivy.uix.label.html#text-alignment-and-wrapping