Reputation: 43
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?
Upvotes: 0
Views: 198
Reputation: 38822
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.
Upvotes: 2