kv 语言的 Kivy Scrollview - id 未定义

Kivy Scrollview in kv language - id not defined

尝试根据文档中给出的示例弄清楚如何用 KV 语言实现一个简单的 ScrollView。我不敢相信我找不到一个这样的例子(只有部分解决方案),所以我认为这很容易。原来不是。

我的问题是我需要使用 add_widget 使用 kivy 脚本中的标签列表填充我的可滚动网格布局。那是因为我要添加的标签数量是可变的(尽管为了简单起见,在下面的示例中该数量是固定的)。但是程序不让我这样做,说我为网格布局对象定义的ID没有定义。因此我无法将标签添加到网格布局。

NameError: name '_gridlayout' is not defined

感谢任何帮助。谢谢

from kivy.app import App
from kivy.uix.scrollview import ScrollView
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.lang import Builder
from kivy.uix.floatlayout import FloatLayout

Builder.load_string('''
<MainScreen>:
    AnchorLayout:
        anchor_x: 'center'
        anchor_y: 'top'
        size_hint: 1, .2
        Label:
            text: "Random text"
    AnchorLayout:
        anchor_x: 'center'
        anchor_y: 'bottom'
        size_hint: 1, .8
        ScrollView:
            GridLayout:
                id: _gridlayout
                cols: 1
                padding: 10
                spacing: 10
                size_hint_y: None
                width: 500           
''')

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

    def buildList(self):
        for i in range(30):
            btn = Label(text=str(i), size_hint_y=None, height=40)
            _gridlayout.add_widget(btn)   # <- ERROR

class SMApp(App):
    def build(self):
        return MainScreen()

if __name__ == '__main__':
    SMApp().run()

更新:更正了下面的脚本。

from kivy.app import App
from kivy.uix.scrollview import ScrollView
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.lang import Builder
from kivy.uix.floatlayout import FloatLayout

Builder.load_string('''
<MainScreen>:
    AnchorLayout:
        anchor_x: 'center'
        anchor_y: 'top'
        size_hint: 1, .2
        Label:
            text: "Random text"
    AnchorLayout:
        anchor_x: 'center'
        anchor_y: 'bottom'
        size_hint: 1, .8
        ScrollView:
            GridLayout:
                id: _gridlayout
                cols: 1
                padding: 10
                spacing: 10
                size_hint_y: None
                width: 500           
''')

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

    def buildList(self):
        for i in range(30):
            btn = Label(text=str(i), size_hint_y=None, height=40)
            self.ids._gridlayout.add_widget(btn)
        self.ids._gridlayout.bind(minimum_height=self.ids._gridlayout.setter('height'))


class SMApp(App):
    def build(self):
        return MainScreen()

if __name__ == '__main__':
    SMApp().run()

Kivy 对先调用 Widget.__init__() 非常挑剔。因此,如果您覆盖 __init__ 小部件,请务必先调用 super().__init__,否则您可能会遇到类似您遇到的错误或 "random" 崩溃。

修复更改

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

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