Kivy 嵌套 BoxLayout 将小部件堆叠在左下角

Gug*_*lie 1 python kivy kivy-language

我正在尝试动态构建一个带有垂直 BoxLayout 的 Kivy 布局,其中包含MyRow可以在运行时更改的不同数量的自定义小部件。 布局示例 每行都是一个水平的 BoxLayout

我没有使用 GridLayout,因为MyRow布局正在开发中,并且可以在不久的将来更改添加小部件等,就像这个例子一样 布局示例2

但通过下面的代码,我只能在窗口的左下角得到彼此堆叠的小部件。

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import StringProperty

class MyRow(Widget):
    a = StringProperty('a')
    b = StringProperty('b')

    def __init__(self, **kwargs):
        super(MyRow, self).__init__(**kwargs)

class MainScreen(Widget):

    rows = [['a1','b1'],['a2','b2']] #example data

    mainLayout = BoxLayout(orientation='vertical', spacing=5)

    def __init__(self, **kwargs):
        super(MainScreen, self).__init__(**kwargs)

        self.add_widget(self.mainLayout)

        for r in self.rows:
            row_widget = MyRow()

            row_widget.a = r[0]
            row_widget.b = r[1]

            self.mainLayout.add_widget(row_widget)

class MyApp(App):

    def build(self):
        return MainScreen()

if __name__ == '__main__':
    MyApp().run()
Run Code Online (Sandbox Code Playgroud)

这是 kv 文件:

<MyRow>
    BoxLayout:
        orientation: "horizontal"
        spacing: 30
        Label:
            id: a_label
            text: root.a
        Label:
            id: b_label
            text: root.b
Run Code Online (Sandbox Code Playgroud)

Pal*_*lim 6

在你的草图中,它说MyRow基于水平 BoxLayout。但事实并非如此。它是建立在widget

简单地改变

class MyRow(Widget):
Run Code Online (Sandbox Code Playgroud)

class MyRow(BoxLayout):
Run Code Online (Sandbox Code Playgroud)

会解决你的问题。

在此输入图像描述


为了获得正确或更好的间距,我会将您的代码更新为以下内容

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import StringProperty
from kivy.base import Builder



class MyRow(BoxLayout):
    a = StringProperty('a')
    b = StringProperty('b')

    def __init__(self, **kwargs):
        super(MyRow, self).__init__(**kwargs)

class MainScreen(BoxLayout):

    rows = [['a1','b1'],['a2','b2']]*5 

    def __init__(self, **kwargs):
        super(MainScreen, self).__init__(**kwargs)
        self.orientation = "vertical"

        for r in self.rows:
            row_widget = MyRow()

            row_widget.a = r[0]
            row_widget.b = r[1]

            self.add_widget(row_widget)



class MyApp(App):

    def build(self):
        return MainScreen()

if __name__ == '__main__':
    MyApp().run()
Run Code Online (Sandbox Code Playgroud)

和你的kv

<MyRow>:
    orientation: "horizontal"
    spacing: 30
    Label:
        id: a_label
        text: root.a
    Label:
        id: b_label
        text: root.b
Run Code Online (Sandbox Code Playgroud)

这给了你在此输入图像描述


要从 python 中的 Boxlayot 继承,请class Row(BoxLayout):在 kv 文件中使用<Row@BoxLayout>: