RockmanJoe
RockmanJoe

Reputation: 1678

How to center buttons in Kivy?

I am new to Python UI programming, and I am trying out Kivy. I want to center some buttons on my screen, but the buttons do not move from the bottom right of the window. I was wondering if anyone could point out what I am doing wrong or am missing?

vgx.kv:

#:kivy 1.9.1

<VgxMainScreen>:
    BoxLayout:
        size_hint: 0.2,0.2
        size: 200, 100
        orientation: 'vertical'

        Button:
            text: 'Game Select'
        Button:
            text: 'Options'
        Button:
            text: 'Controllers'

<VgxUI>:
    AnchorLayout:
        anchor_x: 'center'
        VgxMainScreen:
            size_hint: 0.2,0.2

<VgxApp>:
    FloatLayout:
        VgxUI:
            center: 0.5, 0.5

VgxApp.py:

import kivy
from kivy.app import App
from kivy.uix.widget import Widget
kivy.require('1.9.1')

class VgxMainScreen(Widget):
    pass

class VgxUI(Widget):
    pass

class VgxApp(App):
    def build(self):
        return VgxUI()

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

Upvotes: 10

Views: 24131

Answers (2)

martin
martin

Reputation: 96969

Edit: Best way to debug what's going on with you widgets is to change their background colors :).

canvas.before:
    Color:
        rgba: X, X, X, 1
    Rectangle:
        pos: self.pos
        size: self.size

The problem was that your BoxLayout wasn't positioned relatively to its parent even though it was inside it.

enter image description here

What I did here is that I positioned the BoxLayout to its parent's size and position using:

size: self.parent.size
pos: self.parent.pos

I also moved the size property from VgxMainScreen to VgxUI because I assume this is more common use-case (you can have multiple VgxMainScreens each with different size). Full code with background colors:

#:kivy 1.9.1

<VgxMainScreen>:
    size_hint: None, None
    canvas.before:
        Color:
            rgba: 1, 0, 0, 1  # red
        Rectangle:
            pos: self.pos
            size: self.size

    BoxLayout:
        canvas.before:
            Color:
                rgba: 0, 0, 1, 1  # blue
            Rectangle:
                pos: self.pos
                size: self.size

        size: self.parent.size  # important!
        pos: self.parent.pos  # important!
        orientation: 'vertical'

        Button:
            text: 'Game Select'
        Button:
            text: 'Options'
        Button:
            text: 'Controllers'

<VgxUI>:
    AnchorLayout:
        canvas.before:
            Color:
                rgba: 1, 1, 1, 1  # white
            Rectangle:
                pos: self.pos
                size: self.size
        size: self.parent.size
        anchor_x: 'center'
        anchor_y: 'center'
        VgxMainScreen:
            size: 200, 100

<VgxApp>:
    FloatLayout:
        VgxUI:
            center: 0.5, 0.5

enter image description here

There's yet another solution to this.

You can use RelativeLayout and all widgets inside it will position relatively to this layout.

<VgxMainScreen>:
    size_hint: None, None

    RelativeLayout:
        pos: self.parent.pos
        size: self.parent.size

        BoxLayout:
            orientation: 'vertical'
            Button:
                text: 'Game Select'
            Button:
                text: 'Options'
            Button:
                text: 'Controllers'

I've personally scratched my head many times when using Kivy and wondered why my widgets aren't positioned as I think they should :).

Upvotes: 12

inclement
inclement

Reputation: 29488

VgxMainScreen is a Widget, so it doesn't apply any positioning or sizing to its children (only Layouts do that), so the BoxLayout has the default position of (0, 0) and size of (100, 100).

Make VgxMainScreen inherit from something else, like a FloatLayout.

Upvotes: 2

Related Questions