Kivy:如何使固定大小的控件居中显示在窗口中
我为这个问题纠结了好几个小时。我有一个自定义的控件,它是从RelativeLayout
派生出来的,大小需要固定。我想让这个控件显示在窗口的中央。除此之外,我还想在它周围放一些普通的控件,比如按钮。花了一整天才把这个控件居中,现在我发现一添加按钮,它就不听话了,怎么都摆不对。请问有没有人能帮我看看我的.kv文件,告诉我哪里出错了?
#:kivy 1.8.0
# This is my fixed-size widget
<DrawableGrid>:
# Note: this is just an example size to keep things simple
size: 500, 500
canvas:
Color:
rgba: 1, 0, 0, 1
Rectangle:
pos: self.pos
size: self.size
# This subclasses BoxLayout
CustomLayout:
orientation: "vertical"
# I put my DrawableGrid inside an AnchorLayout in the hope that it might
# behave in some way like the documentation says it does. No such luck.
# This should be taking up the entire top half of the window.
AnchorLayout:
size_hint: 1, 1
# This anchor_x/anchor_y stuff seemingly does nothing.
anchor_x: "center"
anchor_y: "center"
# This should be appearing as a red rectangle of size 500x500
DrawableGrid:
# This next line was needed to set a custom size in the first place
size_hint: 0, 0
# This appears exactly as expected, filling the bottom half of the window.
Button:
id: next_button
text: "Next"
所以,简单说一下,我现在想要的是:
- 窗口被分成上下两个部分(也就是上半部分和下半部分)
- 上半部分应该包含我的自定义控件,大小为500x500,居中显示,周围什么都没有。这个控件应该显示为一个红色的正方形。
- 下半部分应该包含一个文本为“下一步”的按钮,填满整个下半部分。
而我实际得到的是这个:
(如你所见,红色正方形明显不见了)
我尝试了很多不同的方法(有些比较笨拙),但都没有成功。请问有没有人能告诉我该怎么解决这个问题?
2 个回答
RelativeLayout
是一种布局方式,它会根据布局的位置来安排所有子元素的位置。其实,所有的子元素都是一些绘图指令,所以说它们的定位都是相对于这个布局的。所有的子元素都会在一个叫 canvas
的画布上绘制,因此在 canvas
中使用的位置必须是相对于布局本身的!比如,当你在 canvas
中指示要在 self.pos
位置绘制一个矩形时,这个位置会像其他子元素一样被转换(换句话说,矩形会在 self.pos + self.pos
的位置绘制)。如果你把矩形的位置改成 0, 0
,那么它就会按照你预期的那样绘制。
为了更好地解释,这里是 RelativeLayout
的默认样式(来自 kivy/data/style.kv
):
<RelativeLayout>:
canvas.before:
PushMatrix
Translate:
xy: self.pos
canvas.after:
PopMatrix
在 canvas
中你放的任何东西都是在 canvas.before
和 canvas.after
之间发生的。
我觉得你想要一个垂直的BoxLayout作为你的根部件。根部件中的第一个部件是RelativeLayout,第二个是你的按钮。这样可以让屏幕分成50/50的两部分。RelativeLayout里面会放一个500x500的部件,位置设置为(self.parent.width-self.width)/2, (self.parent.height-self.height)/2,这样它就会在屏幕中间显示。
注意:在下面的代码示例中,我用的是100x100的部件,因为500x500的部件在我的屏幕上放不下。
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
kv = """
<Test>:
orientation: "vertical"
RelativeLayout:
GridLayout:
pos: (self.parent.width-self.width)/2, (self.parent.height-self.height)/2
size_hint: None, None
size: 100, 100
canvas:
Color:
rgba: 1, 0, 0, 1
Rectangle:
pos: self.pos
size: self.size
Button:
text: "Next"
"""
Builder.load_string(kv)
class Test(BoxLayout):
def __init__(self, **kwargs):
super(Test, self).__init__(**kwargs)
class TestApp(App):
def build(self):
return Test()
if __name__ == '__main__':
TestApp().run()