Search code examples
pythonkivy-languagegrid-layout

Adjusting Checkbox and Label alignment in a GridLayout


I am relatively new to Kivy, and I'm having problems adjusting checkboxes and their associated labels within a GridLayout. With reference to the image below...

Import Dialog with Grid Layout

In the screenshot above, there are three GridLayout widgets, which contain checkboxes and labels, arranged in 4 columns. I want the columns containing the checkboxes to be narrow, and the columns containing the labels to split the remaining space.

My questions are:

  1. The labels in the second column are quite distant, horizontally, from the checkboxes that they describe in the first column. How can I get them to be closer, as with the widgets in columns 3 & 4?

  2. The checkboxes are not vertically-aligned with the labels that describe them. How can I vertically-align these widgets?

UPDATE: I have tried adding height (to match the checkboxes), valign and padding (0,0,0,0) attributes to the labels, but it has not changed the vertical alignment in the slightest.

  1. I wanted a little space above each section heading, but I wasn't sure how to do that without doing a bunch of manual calculations and playing around with the height of each GridLayout. So, to let Kivy figure this out, I added an extra row with an empty label. Is there a better way to do this?

  2. It's not clear to me from the online documentation or the demo programs how to determine which of these checkboxes (i.e. radio buttons) was selected when the user clicks Load. Must I do an id search in the app to find each checkbox by its id, and then figure out which one is 'True'? Or is there a better way?

Here is my kivy-language code:

<ImportTypeDialog>:
    BoxLayout:
        orientation: "vertical"
        size: root.size
        pos: root.pos

        Label:
            text: '[i]Which type of data are you importing?[/i]'
            markup: 'True'
            text_size: self.width, None
            size: self.texture_size
            halign: 'left'

        Label:
            text: '[u][size=16]Customer-related items[/size][/u]'
            markup: 'True'
            text_size: self.width, None
            size: self.texture_size
            halign: 'left'

        GridLayout:
            cols: 4
            spacing: '8dp'
            size_hint_y: None
            CheckBox:
                id: chkBoxCustomerAddresses
                size_hint_y: None
                size_hint_x: None
                height: '14dp'
                width: '30dp'
                group: 'importTypes'
            Label:
                text: 'Addresses'
                text_size: self.width, None
                halign: 'left'
            CheckBox:
                id: chkBoxCustomerMessaging
                size_hint_y: None
                size_hint_x: None
                height: '14dp'
                width: '30dp'
                group: 'importTypes'
            Label:
                text: 'Electronic Messaging'
                text_size: self.width, None
                halign: 'left'
            CheckBox:
                id: chkBoxCustomerCommunications
                size_hint_y: None
                size_hint_x: None
                height: '14dp'
                width: '30dp'
                group: 'importTypes'
            Label:
                text: 'Communications'
                text_size: self.width, None
            CheckBox:
                id: chkBoxCustomerTransactions
                size_hint_y: None
                size_hint_x: None
                height: '14dp'
                width: '30dp'
                group: 'importTypes'
            Label:
                text: 'Transactions'
                text_size: self.width, None
            Label:
                text: ' '
                text_size: self.width, None

        Label:
            text: '[u][size=16]Supplier-related items[/size][/u]'
            markup: 'True'
            text_size: self.width, None
            size: self.texture_size
            halign: 'left'

        GridLayout:
            cols: 4
            spacing: '8dp'
            size_hint_y: None
            CheckBox:
                id: chkBoxSupplierAddresses
                size_hint_y: None
                size_hint_x: None
                height: '14dp'
                width: '30dp'
                group: 'importTypes'
            Label:
                text: 'Addresses'
                text_size: self.width, None
                halign: 'left'
            CheckBox:
                id: chkBoxSupplierMessaging
                size_hint_y: None
                size_hint_x: None
                height: '14dp'
                width: '30dp'
                group: 'importTypes'
            Label:
                text: 'Electronic Messaging'
                text_size: self.width, None
                halign: 'left'
            CheckBox:
                id: chkBoxSupplierCommunications
                size_hint_y: None
                size_hint_x: None
                height: '14dp'
                width: '30dp'
                group: 'importTypes'
            Label:
                text: 'Communications'
                text_size: self.width, None
            CheckBox:
                id: chkBoxSupplierTransactions
                size_hint_y: None
                size_hint_x: None
                height: '14dp'
                width: '30dp'
                group: 'importTypes'
            Label:
                text: 'Transactions'
                text_size: self.width, None
            Label:
                text: ' '
                text_size: self.width, None

        Label:
            text: '[u][size=16]Employee-related items[/size][/u]'
            markup: 'True'
            text_size: self.width, None
            size: self.texture_size
            halign: 'left'

        GridLayout:
            cols: 4
            spacing: '8dp'
            size_hint_y: None
            CheckBox:
                id: chkBoxEmployeeAddresses
                size_hint_y: None
                size_hint_x: None
                height: '14dp'
                width: '30dp'
                group: 'importTypes'
            Label:
                text: 'Addresses'
                text_size: self.width, None
                halign: 'left'
            CheckBox:
                id: chkBoxEmployeeMessaging
                size_hint_y: None
                size_hint_x: None
                height: '14dp'
                width: '30dp'
                group: 'importTypes'
            Label:
                text: 'Electronic Messaging'
                text_size: self.width, None
                halign: 'left'
            CheckBox:
                id: chkBoxEmployeeCommunications
                size_hint_y: None
                size_hint_x: None
                height: '14dp'
                width: '30dp'
                group: 'importTypes'
            Label:
                text: 'Communications'
                text_size: self.width, None
            CheckBox:
                id: chkBoxEmployeeTransactions
                size_hint_y: None
                size_hint_x: None
                height: '14dp'
                width: '30dp'
                group: 'importTypes'
            Label:
                text: 'Transactions'
                text_size: self.width, None
            Label:
                text: ' '
                text_size: self.width, None

        BoxLayout:
            orientation: "horizontal"
            size_hint_y: None
            height: 30
            Button:
                text: "Cancel"
                on_release: root.cancel()
            Button:
                text: "Load"
                on_release: app.ImportFile(filechooser.path, filechooser.selection)

Solution

  • I was able to get pretty much the layout I wanted by using this Kivy-language code:

    <ImportTypeDialog>:
        BoxLayout:
            orientation: "vertical"
            size: root.size
            pos: root.pos
    
            Label:
                text: '[i]Which type of data are you importing?[/i]'
                markup: 'True'
                text_size: self.width, None
                size: self.texture_size
                halign: 'left'
    
            Label:
                text: '[u][size=16]Customer-related items[/size][/u]'
                markup: 'True'
                text_size: self.width, None
                size: self.texture_size
                halign: 'left'
    
            GridLayout:
                cols: 4
                spacing: '8dp'
                size_hint_y: None
                CheckBox:
                    id: chkBoxCustomerAddresses
                    size_hint_y: None
                    size_hint_x: None
                    height: '14dp'
                    width: '30dp'
                    group: 'importTypes'
                Label:
                    text: 'Addresses'
                    text_size: self.width, None
                    size_hint_y: None
                    height: '18dp'
                    halign: 'left'
                CheckBox:
                    id: chkBoxCustomerMessaging
                    size_hint_y: None
                    size_hint_x: None
                    height: '14dp'
                    width: '30dp'
                    group: 'importTypes'
                Label:
                    text: 'Electronic Messaging'
                    text_size: self.width, None
                    size_hint_y: None
                    height: '18dp'
                    halign: 'left'
                CheckBox:
                    id: chkBoxCustomerCommunications
                    size_hint_y: None
                    size_hint_x: None
                    height: '14dp'
                    width: '30dp'
                    group: 'importTypes'
                Label:
                    text: 'Communications'
                    text_size: self.width, None
                    size_hint_y: None
                    height: '18dp'
                    halign: 'left'
                CheckBox:
                    id: chkBoxCustomerTransactions
                    size_hint_y: None
                    size_hint_x: None
                    height: '14dp'
                    width: '30dp'
                    group: 'importTypes'
                Label:
                    text: 'Transactions'
                    text_size: self.width, None
                    size_hint_y: None
                    height: '18dp'
                    halign: 'left'
    
            Label:
                text: '[u][size=16]Supplier-related items[/size][/u]'
                markup: 'True'
                text_size: self.width, None
                size: self.texture_size
                halign: 'left'
    
            GridLayout:
                cols: 4
                spacing: '8dp'
                size_hint_y: None
                CheckBox:
                    id: chkBoxSupplierAddresses
                    size_hint_y: None
                    size_hint_x: None
                    height: '14dp'
                    width: '30dp'
                    group: 'importTypes'
                Label:
                    text: 'Addresses'
                    text_size: self.width, None
                    size_hint_y: None
                    height: '18dp'
                    halign: 'left'
                CheckBox:
                    id: chkBoxSupplierMessaging
                    size_hint_y: None
                    size_hint_x: None
                    height: '14dp'
                    width: '30dp'
                    group: 'importTypes'
                Label:
                    text: 'Electronic Messaging'
                    text_size: self.width, None
                    size_hint_y: None
                    height: '18dp'
                    halign: 'left'
                CheckBox:
                    id: chkBoxSupplierCommunications
                    size_hint_y: None
                    size_hint_x: None
                    height: '14dp'
                    width: '30dp'
                    group: 'importTypes'
                Label:
                    text: 'Communications'
                    text_size: self.width, None
                    size_hint_y: None
                    height: '18dp'
                    halign: 'left'
                CheckBox:
                    id: chkBoxSupplierTransactions
                    size_hint_y: None
                    size_hint_x: None
                    height: '14dp'
                    width: '30dp'
                    group: 'importTypes'
                Label:
                    text: 'Transactions'
                    text_size: self.width, None
                    size_hint_y: None
                    height: '18dp'
                    halign: 'left'
    
            Label:
                text: '[u][size=16]Employee-related items[/size][/u]'
                markup: 'True'
                text_size: self.width, None
                size: self.texture_size
                halign: 'left'
    
            GridLayout:
                cols: 4
                spacing: '8dp'
                size_hint_y: None
                CheckBox:
                    id: chkBoxEmployeeAddresses
                    size_hint_y: None
                    size_hint_x: None
                    height: '14dp'
                    width: '30dp'
                    group: 'importTypes'
                Label:
                    text: 'Addresses'
                    text_size: self.width, None
                    size_hint_y: None
                    height: '18dp'
                    halign: 'left'
                CheckBox:
                    id: chkBoxEmployeeMessaging
                    size_hint_y: None
                    size_hint_x: None
                    height: '14dp'
                    width: '30dp'
                    group: 'importTypes'
                Label:
                    text: 'Electronic Messaging'
                    text_size: self.width, None
                    size_hint_y: None
                    height: '18dp'
                    halign: 'left'
                CheckBox:
                    id: chkBoxEmployeeCommunications
                    size_hint_y: None
                    size_hint_x: None
                    height: '14dp'
                    width: '30dp'
                    group: 'importTypes'
                Label:
                    text: 'Communications'
                    text_size: self.width, None
                    size_hint_y: None
                    height: '18dp'
                    halign: 'left'
                CheckBox:
                    id: chkBoxEmployeeTransactions
                    size_hint_y: None
                    size_hint_x: None
                    height: '14dp'
                    width: '30dp'
                    group: 'importTypes'
                Label:
                    text: 'Transactions'
                    text_size: self.width, None
                    size_hint_y: None
                    height: '18dp'
                    halign: 'left'
    
            BoxLayout:
                orientation: "horizontal"
                size_hint_y: None
                height: 30
                Button:
                    text: "Cancel"
                    on_release: root.cancel()
                Button:
                    text: "Load"
                    on_release: app.ImportFile()
    

    It's a bit long and somewhat repetitive, but it's conceptually pretty simple and easy to maintain. Mainly, I had to add size_hint_y and height to each checkbox label. This solved #2, and somehow, magically, #1 and #3. I still need to figure out #4, but the main point of this post was to figure out the layout.