Centering TextInput within a BoxLayout in Kivy

Totem picture Totem · Apr 2, 2014 · Viewed 7.6k times · Source

Here is a screenshot of my kivy app. I am trying to get the TextInput in the bottom left to be centered in the BoxLayout which it is in, and I don't want it to be the same size as the layout, I want it to be much smaller. This BoxLayout in question resides in the bottom half of the screen. I have tried setting the TextInputs propertycenter:self.parent.center but this doesn't work. As you can see, I have printed the center coords from the BoxLayout into the TextInput using that very line, self.parent.center, with the correct result. Yet, setting the TextInputs center or position to these coords is not centering it, it doesn't move... what am I doing wrong?

py file:

import kivy
from kivy.app import App
from kivy.uix.widget import Widget 
from kivy.uix.label import Label 
from kivy.uix.boxlayout import BoxLayout

class TimeTabler(Widget):

    pass

class TimerApp(App):

    def build(self):
        return TimeTabler()

if __name__ == "__main__":
    TimerApp().run()

****kv file:****

#:kivy 1.0

BoxLayout:
    orientation: 'vertical'
    size: root.size

    BoxLayout:
        orientation: 'vertical'

        Label:
            text: 'TimeTabler'

    BoxLayout:
        TextInput:
            text: '%s' % (self.parent.center) # why does this work here
            size_hint: None, None
            width: sp(200)
            height: sp(30)
            center: self.parent.center # but not here

Answer

inclement picture inclement · Apr 2, 2014

You gave the TextInput size_hint: None, None, therefore the BoxLayout doesn't try to manually give it the right size, and it assumes the default size of 100, 100. Just delete the size_hint line to fix it.

Also, several widgets have lines like size: self.size. This is meaningless, self refers to the widget itself, and clearly the line does nothing since it just tries to set the size to what it already is.

Things would also be simpler if you made your TimeTabler inherit from BoxLayout instead of Widget. That way you wouldn't need to manually set it's child BoxLayout's size.

Edit: It looks like I misunderstood what you wanted, here's an example that uses an AnchorLayout to center the TextInput:

<TimeTabler>

    BoxLayout:
        orientation: 'vertical'
        size: root.size
        on_touch_down: print self.pos, self.size

        canvas:
            Color: 
                rgba: 0, 1, 1, .3
            Rectangle:
                size: self.size
                pos: self.pos

        BoxLayout:

            orientation: 'vertical'

            size: self.size
            Label:
                text: 'TimeTabler'

        BoxLayout:

            id: bl

            on_touch_down: print 'center', self.center
            canvas:
                Color:
                    rgb: 1,1,1
                Line:
                    rectangle: self.x, self.y, self.width, self.height

            AnchorLayout:
                TextInput:
                    size_hint: None, None
                    text: '%s, %s' % (self.get_center_x(), self.get_center_y())

I think your problem was the BoxLayout automatically sets the position of the TextInput even when it is setting its own size. A simple way around this is to just next the TextInput in another widget, in this case an AnchorLayout that takes care of the centering for you. You could also just use a Widget and your previous mechanism of setting the TextInput center.