'Kivy center button
I'm making a simple test app in Kivy for learning:
class MyWidget(GridLayout):
def __init__(self, **kwargs):
super(MyWidget, self).__init__(**kwargs)
Window.clearcolor = (1, 1, 1, 1)
class PhoneApp(App):
def build(self):
return MyWidget()
if __name__ == "__main__":
PhoneApp().run()
This my .kv:
#:kivy 2.1.0
<Label>
size_hint_y: None
height: self.texture_size[1]
color: 0, 0, 0, 1
<Image>
size_hint_y: None
height: self.texture_size[1]
<Button>
size_hint_x: None
size_hint_y: None
width: self.texture_size[0]
height: self.texture_size[1]
<GridLayout>
cols: 1
size_hint: (0.5, 0.9)
pos_hint: {"center_x": 0.5, "center_y": 0.5}
<MyWidget>:
Image:
source: "captus.png"
Label:
text: "Test Message"
Button:
text: "Second test"
The problem is that the button isn't aligned, as you can see in the following image:
The green button "Second test" should be centered, in the middle of the window, like "Test Message" is.
I've been playing with pos_hint: {'center_x':0.5, 'center_y':0.5} but I can't manage to center that button...
How can I center the "Second test" button?
Solution 1:[1]
The problem is that a GridLayout does not honor pos_hint at all. So getting a widget centered in a GridLayout cell takes a bit of planning.
One way is to just make the Button fill the width of the GridLayout cell. That doesn't actually center the Button, but the text of the Button will be centered. To so this, just remove the size_hint_x: None line from the <Button>: rule in your kv.
Another way is to put the Button in a container that fills the GridLayout cell, and center the Button in that container. An AnchorLayout serves just that purpose. Try replacing the Button part of your <MyWidget>: rule with:
AnchorLayout:
size_hint_y: None
height: butt.height # same height as the Button
Button:
id: butt
text: "Second test"
A third option is to not use GridLayout. If you are only using 1 column or 1 row, a BoxLayout may be a better approach. And a BoxLayout supports pos_hints (partially, see the documentation). To use this approach, change MyWidget to extend BoxLayout:
class MyWidget(BoxLayout):
def __init__(self, **kwargs):
super(MyWidget, self).__init__(**kwargs)
Window.clearcolor = (1, 1, 1, 1)
Then you can use the pos_hint as suggested by @mohammad-alqashqish in the kv:
<Label>
size_hint_y: None
height: self.texture_size[1]
color: 0, 0, 0, 1
<Image>
size_hint_y: None
height: self.texture_size[1]
<Button>
size_hint_x: None
size_hint_y: None
width: self.texture_size[0]
height: self.texture_size[1]
<GridLayout>
cols: 1
size_hint: (0.5, 0.9)
pos_hint: {"center_x": 0.5, "center_y": 0.5}
<MyWidget>:
orientation: 'vertical'
Image:
source: "tester.png"
Label:
text: "Test Message"
Button:
text: "Second test"
pos_hint: {'center_x': 0.5}
One other thing to note. When you make a rule in kv for a standard widget, like <Label>:, that rule will be applied to every Label you create in your app after that kv is loaded.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | John Anderson |

