在Kivy的GridLayout中,是否可以为特定小部件指定特定的网格?
我已经使用PyQt很长时间了,我知道如果我们在PyQt中使用QGridLayout,就可以在特定的网格位置放置特定的控件。
比如说:
grid = QtGui.QGridLayout()
grid.setSpacing(10)
grid.addWidget(self.Banner,0,0,1,4,QtCore.Qt.AlignTop | QtCore.Qt.AlignCenter)
grid.addWidget(self.RefNo,1,0,1,2)
grid.addWidget(self.RefNoText,1,2,1,2)
在这里,self.banner
、self.Refno
和self.RefNoText
都是一些控件。在这种情况下,我们可以指定控件,然后指定它所在的行和列。请问在Kivy中也能这样做吗?
我在Kivy中尝试过,但似乎在Kivy里我们需要先指定行和列,然后添加控件时,它们会自动排列?
有没有什么想法?
2 个回答
Kivy的GridLayout和PyQt的GridLayout不太一样,所以在这个特定的情况下不太合适。
一个比较自然的选择是使用FloatLayout,通过pos_hint
和size_hint
来放置小部件。你甚至可以创建一个FloatLayout的子类,自动处理网格中的位置。
其实,我之前就做过这样的事情,你可以在这里找到我的代码。我的SparseGridLayout使用子小部件的col
和row
属性来正确定位它。如果你愿意,也可以重写add_widget
,让它的用法和qt的语法完全一样,但最重要的是要理解我如何使用FloatLayout来放置小部件。
在Kivy中,当我们往GridLayout(网格布局)里添加小部件时,只需要指定行和列,或者两者都指定。
接下来,布局的具体位置就交给Kivy来处理,它会根据我们的设置自动填充。
你可以查看GridLayout的官方文档。
里面有一个很不错的动图,能帮助你理解小部件是如何在GridLayout中排列的。
所以,针对你的问题,答案是否定的。我们不能指定小部件放在哪里,但我们可以通过添加小部件的方式,让它们正确地排列。
一开始,我在让一个小部件占据多个单元格时遇到了一些困难,比如这样:
<2 cells><1cell>
+--------+-----+
|Big | |
|Widget | |
+--------+-----+
| | | |
| | | |
+---+----+-----+
不过,这个问题可以通过将整行设置为BoxLayout(盒子布局)来解决。像这样:
<1 big BoxLayout>
+--------+-----+
|Big | |
|Widget | |
+--------+-----+
| | | |
| | | |
+---+----+-----+
<1 more BoxLayout>
这样,每个BoxLayout就只占用一个单元格。你可以通过BoxLayout自定义小部件之间的间距,然后再放到Grid中。
下面是如何在Kv语言中实现这一点:
<MyGrid>
cols=1 # Actually, you can just use a vertical box
BoxLayout:
BigWidget:
# Properties
SmallWidget:
# Properties
BoxLayout:
SmallWidget:
# Properties
SmallWidget:
# Properties
SmallWidget:
# Properties
Kivy会自动用1列来填充Grid。
所以,通过嵌套布局,你就能得到想要的效果。