首页 > 解决方案 > 如何从另一个“屏幕”上的输入填充recycleview

问题描述

再会

我想要完成的是在一个屏幕上输入文本,然后让它在另一个屏幕上创建一个按钮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()

标签: pythonkivy

解决方案


问题是您正在填充 的dataapp.rvs但这是由以下行创建的:

rvs = RVScreen()

这会创建一个与GUI 中显示的RVScreen完全无关的新实例。RVScreen为了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.


推荐阅读