屏幕下 recycleview 数据的 kivy 问题

kivy issue with recycleview data when under screen

Kivy 新手,在通过屏幕使用 recycleView 时遇到问题。如果我将屏幕设置为以 self.manager = MainWidget() 开始进行测试,则数据加载正常,但是当将其正确设置为 ScreenManager() 时,self.recycleView 始终为 NoneType 并在我尝试设置时崩溃self.recycleView.数据。我假设这是某种参考问题,因为当我使用 on_parent 和 MainWidget 加载它时它有效

直接进入 MainWidget():

        self.manager = MainWidget()

使用 MyScreenManager()

        self.manager = MyScreenManager()

结果错误:

File "C:/path/to/main.py", line 42, in on_parent {"name": "name1"}, {"name": "name2"}, {"name": "name3"}, {"name": "name4"} AttributeError: 'NoneType' object has no attribute 'data'

Process finished with exit code 1

main.py

from kivy.app import App
from kivy.properties import StringProperty, NumericProperty, BooleanProperty, ObjectProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.floatlayout import FloatLayout
from navigation_screen_manager import NavigationScreenManager


class MyScreenManager(NavigationScreenManager):
    pass


class MainMenu(BoxLayout):
    pass


class ItemWidget(BoxLayout):
    id = NumericProperty()
    name = StringProperty()
    links_to = StringProperty()
    is_disabled = BooleanProperty()
    description = StringProperty()

    def get_menu(self, id):
        if id == 9:
            quit()
        else:
            print("you pressed" + str(id))


class MainWidget(FloatLayout):
    recycleView = ObjectProperty()

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        print('initialized')

        self.items = ['item1', 'item2']

    def on_parent(self, widget, parent):
        print(f'parent of {self} is {self.parent}')
        self.recycleView.data = [
            {"name": "name1"}, {"name": "name2"}, {"name": "name3"}, {"name": "name4"}
        ]


class TheLabApp(App):
    manager = ObjectProperty(None)

    def build(self):
        self.manager = MyScreenManager()

        # return main interface
        return self.manager


TheLabApp().run()

thelab.kv

#: import navigation_screen_manager navigation_screen_manager
#: import utils kivy.utils
#:set color1 "#DD7835"
#:set color2 "#D8D8D8"

<CoverImage@CoverBehavior+Image>:
    reference_size: self.texture_size

<MyScreenManager>
    Screen:
        name: "MainWidget"
        MainWidget:
<ItemWidget>:
    BoxLayout:
        size_hint_max_x: dp(300)
        size_hint_min_x: dp(150)
        orientation: "vertical"
        Button:
            text_size: self.size
            background_color: 0,0,0,0
            halign: "left"
            valign: "center"
            text: root.name
            #on_press: quit() #root.get_menu(root.id)
            BoxLayout:
                spacing: dp(10)
                FitLabel:
                    font_size: dp(22)
                    bold: True
        LeftAlignLabel:
            text: "description"
            color: utils.get_color_from_hex(color2)
<MainWidget>:
    recycleView: recycleView
    CoverImage:
        source: 'images/menu_background.jpg'
        canvas:
            Color:
                rgba: 0, 0, 0, .6
            Rectangle:
                pos: self.pos
                size: self.size
    BoxLayout:
        orientation: "vertical"
        Image:
            source: 'images/small_logo.png'
            allow_stretch: True
            size_hint: None, None
            size: dp(150), dp(60)
            pos_hint: { "center_x": .5 }
        TitleLabel:
            text: "Title Label"
        BoxLayout:
            padding: dp(20), dp(20)
            RecycleView:
                id: recycleView
                viewclass: 'ItemWidget'
                RecycleBoxLayout:
                    default_size: None, dp(56)
                    default_size_hint: 1, None
                    size_hint_y: None
                    height: self.minimum_height
                    orientation: "vertical"
                    spacing: dp(16)




<FitLabel@Label>:
    size_hint: None, None
    size: self.texture_size
<TitleLabel@FitLabel>:
    font_size: dp(22)
    bold: True
    padding: dp(16), dp(3)
    canvas.before:
        Color:
            rgb: utils.get_color_from_hex(color1)
        Rectangle:
            pos: self.pos
            size: self.size
<LeftAlignLabel@Label>
    text_size: self.size
    halign: "left"
    valign: "center"
    canvas.before:
        Color:
            #rgb: utils.get_random_color()
            rgba: 0, 0, 0, 0
        Rectangle:
            pos: self.pos
            size: self.size

navigation_screen_manager.py

from kivy.uix.screenmanager import ScreenManager


class NavigationScreenManager(ScreenManager):
    screen_stack = []

    def push(self, screen_name):
        if screen_name not in self.screen_stack:
            self.screen_stack.append(self.current)
            self.transition.direction = 'left'
            self.current = screen_name

    def pop(self):
        if len(self.screen_stack) > 0:
            screen_name = self.screen_stack[-1]
            self.transition.direction = 'right'
            del self.screen_stack[-1]
            self.current = screen_name

因为你的recycleViewMainWidgetProperty,你可以在设置recycleView时触发设置数据,像这样:

class MainWidget(FloatLayout):
    recycleView = ObjectProperty()

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        print('initialized')

        self.items = ['item1', 'item2']

    def on_recycleView(self, widget, rv):
        self.recycleView.data = [
            {"name": "name1"}, {"name": "name2"}, {"name": "name3"}, {"name": "name4"}
        ]