Как заполнить recycleview из ввода на другом `` экране '' - PullRequest
0 голосов
/ 09 мая 2020

добрый день

то, что я пытаюсь выполнить sh, - это ввести текст на одном экране, а затем создать кнопку на другом экране в recycleview, где, если я продолжу добавлять кнопки, recycleview продолжает заполняться. Я бы предположил, что функция button1 обновит rvs.rv.data, а recycleview будет использовать само обновление. не могли бы вы указать мне правильное направление, пожалуйста?

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.screenmanager import Screen, ScreenManager


kv = """
<custombutton@BoxLayout>:
    canvas.before:
        Color:
            rgba: 0.5, 0.5, 0.5, 1
        Rectangle:
            size: self.size
            pos: self.pos
    value: ''
    Button:
        text: root.value
<Root>:
    RVScreen:
        name: 'Rv'
    InputScreen:
        name: 'input_screen'


<InputScreen>:
    name: "input_screen"

    orientation: "vertical"
    BoxLayout:
        orientation: "vertical"

        TextInput:
            id: textinput

        Button:

            text: "hi"
            on_press: print(app.rvs.rv.data)
            on_press: app.rvs.button1('some_value')

        Button:
            text: 'rvscreen'
            on_press: root.manager.current = 'Rv'

<RVScreen>:
    name: 'Rv'
    rv: rv
    orientation: "vertical"
    BoxLayout:
        orientation: "vertical"

        Button:
            text: 'refresh'
            on_press: root.rv.refresh_from_data()
            on_press: print(app.rvs.rv.data)

        Button:

            text: "input page"
            on_press: root.manager.current = 'input_screen'


        RecycleView:
            id: rv
            viewclass: 'custombutton'
            RecycleBoxLayout:
                default_size: None, dp(56)
                default_size_hint: 1, None
                size_hint_y: None
                height: self.minimum_height
                orientation: 'vertical'
"""

Builder.load_string(kv)


class Root(ScreenManager):
    pass


class RVScreen(Screen):
    def __init__(self, **kwargs):
        super(RVScreen, self).__init__(**kwargs)


    def button1(self, value):
        self.rv.data.insert(0, {'value': value or 'default value'})


class InputScreen(Screen):
    pass


class TestApp(App):
    rvs = RVScreen()

    def build(self):
        return Root()


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

1 Ответ

0 голосов
/ 09 мая 2020

Проблема в том, что вы заполняете data из app.rvs, но это создается строкой:

rvs = RVScreen()

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

Мне нравится это с помощью метода в App, просто потому, что он делает код попроще. Итак, вот модифицированная версия вашего кода, которая работает по-моему:

from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import Screen, ScreenManager


kv = """
<custombutton@BoxLayout>:
    canvas.before:
        Color:
            rgba: 0.5, 0.5, 0.5, 1
        Rectangle:
            size: self.size
            pos: self.pos
    value: ''
    Button:
        text: root.value
<Root>:
    RVScreen:
        name: 'Rv'
    InputScreen:
        name: 'input_screen'


<InputScreen>:
    name: "input_screen"

    orientation: "vertical"
    BoxLayout:
        orientation: "vertical"

        TextInput:
            id: textinput

        Button:
            text: "hi"
            on_press: app.add_data(textinput.text)

        Button:
            text: 'rvscreen'
            on_press: root.manager.current = 'Rv'

<RVScreen>:
    name: 'Rv'
    rv: rv
    orientation: "vertical"
    BoxLayout:
        orientation: "vertical"

        Button:
            text: 'refresh'
            on_press: rv.refresh_from_data()

        Button:
            text: "input page"
            on_press: root.manager.current = 'input_screen'


        RecycleView:
            id: rv
            viewclass: 'custombutton'
            RecycleBoxLayout:
                default_size: None, dp(56)
                default_size_hint: 1, None
                size_hint_y: None
                height: self.minimum_height
                orientation: 'vertical'
"""

Builder.load_string(kv)


class Root(ScreenManager):
    pass


class RVScreen(Screen):
    pass


class InputScreen(Screen):
    pass


class TestApp(App):
    # rvs = RVScreen()  # this code does nothing useful

    def build(self):
        return Root()

    def add_data(self, value):

        # get the `Screen` instance
        rvs = self.root.get_screen('Rv')

        # insert the new value into the data
        rvs.ids.rv.data.insert(0, {'value': value or 'default value'})


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

Я также сделал небольшую модификацию, так что новый value происходит от TextInput.

...