Kivy RecycleView не отображает данные после перехода на экран

Я изменил пример Kivy RecycleView и поместил его на экран с меню, но теперь он показывает пустые страницы вместо данных. Я подозреваю, что корень изменился, но я не могу подключить RecycleView к правильному источнику.

Честно говоря, я думаю, что мне нужно больше работать над тем, чтобы научиться правильно связывать разные объекты.

Моя модифицированная версия с проблемой:

from kivy.app import App
from kivy.properties import ObjectProperty, StringProperty, NumericProperty, ListProperty
from kivy.uix.recycleview.views import RecycleDataViewBehavior
from kivy.uix.boxlayout import BoxLayout
from kivy.lang.builder import Builder

from kivy.uix.screenmanager import Screen, ScreenManager

KV = """

<SomeMenu_ActionBar@ActionBar>:

    ActionView:
        id: ActionView
        HiddenIcon_ActionPrevious:
        ActionButton:
            text: 'Stop'
            on_release:  app.stop()
       
       
<HiddenIcon_ActionPrevious@ActionPrevious>:

    
<MainBox>:
    orientation: 'vertical'
    canvas.before:
        Color:
            rgb: .6, .6, .6
        Rectangle:
            pos: self.pos
            size: self.size
            # source: 'data/background.png'

    MyManager:
        id: sm
        RVScreen:
            id: rvscreen

    SomeMenu_ActionBar:
        id: ActionBar


<RecycleItem>:
    orientation: 'horizontal'
    Label:
        text: root.label_text
    TextInput:
        text: root.input_text
        on_text: root.set_text(self.text)

RecycleView:
    data: app.data
    viewclass: 'RecycleItem'
    RecycleBoxLayout:
        spacing: 10
        default_size: None, dp(80)
        default_size_hint: 1, None
        orientation: 'vertical'
        size_hint_y: None
        height: self.minimum_height


<RVScreen>:
    id: "rvscreen"
    BoxLayout:
        orientation: "vertical"
        RecycleView:
        Button:
            text: 'Previous screen'
            size_hint: None, None
            size: 150, 50
            on_release: root.manager.current = root.manager.previous()
"""

class RecycleItem(RecycleDataViewBehavior, BoxLayout):
    owner = ObjectProperty()
    index = NumericProperty(0)
    input_text = StringProperty()
    label_text = StringProperty()

    def set_text(self, text):
        if self.owner is not None:
            self.owner.data[self.index]['input_text'] = text
    
    def refresh_view_attrs(self, rv, index, data):
        self.index = index
        return super(RecycleItem, self).refresh_view_attrs(rv, index, data)

class MainBox(BoxLayout):
    """Mainbox under MainApp
    It contains the ScreenManager
    """
    pass

class RVScreen(Screen):
    pass

class MyManager(ScreenManager):
    """The screen manager that handles app screens
    """
    pass

class Test(App):
    data = ListProperty()

    def build(self):
        self.data = [{'label_text': "Label "+str(x), "input_text": "Input "+str(x), 'owner': self} for x in range(20)]
        Builder.load_string(KV)
        return MainBox()

Test().run()

Оригинальный рабочий пример:

from kivy.app import App
from kivy.properties import ObjectProperty, StringProperty, NumericProperty, ListProperty
from kivy.uix.recycleview.views import RecycleDataViewBehavior
from kivy.uix.boxlayout import BoxLayout
from kivy.lang.builder import Builder

KV = """
<RecycleItem>:
    orientation: 'horizontal'
    Label:
        text: root.label_text
    TextInput:
        text: root.input_text
        on_text: root.set_text(self.text)

RecycleView:
    data: app.data
    viewclass: 'RecycleItem'
    RecycleBoxLayout:
        spacing: 10
        default_size: None, dp(80)
        default_size_hint: 1, None
        orientation: 'vertical'
        size_hint_y: None
        height: self.minimum_height


<RVScreen>:
    BoxLayout:
        orientation: "vertical"
        RecycleView:
        Button:
            text: 'Previous screen'
            size_hint: None, None
            size: 150, 50
            on_release: root.manager.current = root.manager.previous()
"""

class RecycleItem(RecycleDataViewBehavior, BoxLayout):
    owner = ObjectProperty()
    index = NumericProperty(0)
    input_text = StringProperty()
    label_text = StringProperty()

    def set_text(self, text):
        if self.owner is not None:
            self.owner.data[self.index]['input_text'] = text
    
    def refresh_view_attrs(self, rv, index, data):
        self.index = index
        return super(RecycleItem, self).refresh_view_attrs(rv, index, data)

class Test(App):
    data = ListProperty()

    def build(self):
        self.data = [{'label_text': "Label "+str(x), "input_text": "Input "+str(x), 'owner': self} for x in range(20)]
        return Builder.load_string(KV)

Test().run()

Где именно в вашем коде вы хотите поставить RecycleView ?

ApuCoder 09.04.2022 10:03

Я хочу иметь в RVScreen. Чуть выше кнопки.

Akkad 09.04.2022 11:55
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
Четыре эффективных способа центрирования блочных элементов в CSS
Четыре эффективных способа центрирования блочных элементов в CSS
У каждого из нас бывали случаи, когда нам нужно отцентрировать блочный элемент, но мы не знаем, как это сделать. Даже если мы реализуем какой-то...
0
2
29
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете определить виджет root несколькими способами.

Если у вас есть метод build в подклассе App и он возвращает какой-то Widget, он будет установлен как виджет root. Или вы можете назначить root правилу kv, загрузив его туда и т. д.

В этом случае в вашем kv-правиле вы определили RecycleView как виджет root, но вы не использовали его в build, чтобы установить его как root.

Тем временем вы вернули MainBox из метода build, поэтому он будет использоваться как виджет root. Опять же, вы загрузили туда правило kv, поэтому дизайн и т. д. будут применены к этому корневому виджету.

Теперь, чтобы добавить RecycleView к RVScreen (как вы упомянули в комментарий) и установить MainBox как виджет root (как вы уже сделали), вы можете изменить свой kvlang следующим образом:

<SomeMenu_ActionBar@ActionBar>:

    ActionView:
        id: ActionView
        HiddenIcon_ActionPrevious:
        ActionButton:
            text: 'Stop'
            on_release:  app.stop()
       
       
<HiddenIcon_ActionPrevious@ActionPrevious>:

    
<MainBox>:
    orientation: 'vertical'
    canvas.before:
        Color:
            rgb: .6, .6, .6
        Rectangle:
            pos: self.pos
            size: self.size
            # source: 'data/background.png'

    MyManager:
        id: sm
        RVScreen:
            id: rvscreen

    SomeMenu_ActionBar:
        id: ActionBar


<RecycleItem>:
    orientation: 'horizontal'
    Label:
        text: root.label_text
    TextInput:
        text: root.input_text
        on_text: root.set_text(self.text)


<RVScreen>:
    id: "rvscreen"
    BoxLayout:
        orientation: "vertical"
        RecycleView:
            data: app.data
            viewclass: 'RecycleItem'
            RecycleBoxLayout:
                spacing: 10
                default_size: None, dp(80)
                default_size_hint: 1, None
                orientation: 'vertical'
                size_hint_y: None
                height: self.minimum_height
        Button:
            text: 'Previous screen'
            size_hint: None, None
            size: 150, 50
            on_release: root.manager.current = root.manager.previous()

Также кажется, что <RVScreen>: в моем исходном примере ничего не делал. кажется, я каким-то образом изменил пример, чтобы добавить экран, в исходном варианте такого экрана не было.

Akkad 09.04.2022 22:29

Другие вопросы по теме