首页 > 解决方案 > Buttonpress 上的 Kivy Python Recycleview 更新

问题描述

我想在按下更新按钮后使我的代码中的回收视图可见。再次按下此按钮后,列表应使用给定的新数据进行更新。问题是更新按钮不能那样工作。

我使代码尽可能易于阅读,因此希望任何人都可以在不需要太多时间的情况下看到问题。

如果我在启动时直接写入数据,我会看到一些输出,所以我猜主要问题是 recycleview 没有更新(我读了很多,但我无法弄清楚)。

主要py:

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


class MainScreen(Screen):

    def update(self):
        Scanner.change_number(self)


class SecondScreen(Screen):
    pass


class RV(RecycleView):
    def __init__(self, **kwargs):
        super(RV, self).__init__(**kwargs)
        print ("Init RV done")

        # By directly writing the Data everything is fine
        # name_list = ['adam', 'peter', 'christine', 'lisa']
        # number_list = ['1923', '1924', '1925', '1929']
        # RV.data = [{'name': name_list[x], 'number': number_list[x]} for x in range(4)]

    def update_list(self, name_list, number_list):
        # this part is not working
        print("Updating...")
        self.data = [{'name': name_list[x], 'number': number_list[x]} for x in range(4)]
        #self.parent.refresh_from_data(self)


class Scanner():
    def __init__(self, **kwargs):
        super(Scanner, self).__init__(**kwargs)
        print("Scanner Init Done")

    def change_number(self):
        # here excluded is some magic function generating numbers
        name_list = ['adam', 'peter', 'christine', 'lisa']
        number_list = ['1923', '1924', '1925', '1929']
        RV.update_list(self, name_list, number_list)


class ScreenManagerApp(App):
    def build(self):
        self.root = Builder.load_file('test.kv')
        root = ScreenManager()
        root.add_widget(MainScreen(name='MainScreen'))
        root.add_widget(SecondScreen(name='SecondScreen'))
        return root


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

测试.kv:

<EachItem@BoxLayout>:
    canvas.before:
        Color:
            rgba: 0.5, 0.5, 0.5, 1
        Rectangle:
            size: self.size
            pos: self.pos
    name: []
    number: []

    GridLayout:
        rows:1
        cols:2
        BoxLayout:
            Label:
                id: Row1
                text: str(" ".join(root.name))
                mipmap: True
            Label:
                id: Row2
                text: str(" ".join(root.number))
                mipmap: True


<RV>:
    id: Hostlist
    bar_width: 20
    scroll_type: ['bars', 'content']
    scroll_wheel_distance: 120
    viewclass: 'EachItem'
    RecycleBoxLayout:
        padding: 10, 0, 10, 0
        size_hint_y: None
        height: self.minimum_height
        default_size: None, 40
        default_size_hint: 1, None
        orientation: 'vertical'
        spacing: 3

<MainScreen>:
    rows: 1
    GridLayout:
        cols: 1
        rows: 3
        spacing: 10
        canvas:
            Color:
                rgba: 1, 1, 1, .1
            Rectangle:
                size: self.size
                pos: self.pos
        FloatLayout:
            height: "100"
            size_hint_y: None
            Button:
                text: "Update"
                pos_hint: {"x":0, "y":0}
                on_press: root.update()
        BoxLayout:
            height: "50"
            size_hint_y: None
            GridLayout:
                padding: 10, 0, 10, 0
                rows:1
                cols:4
                Label:
                    text: "Row1"
                    canvas.before:
                        Color:
                            rgba: 0.3, 0.3, 0.3, 1
                        Rectangle:
                            pos: self.pos
                            size: self.size
                Label:
                    text: "Row2"
                    canvas.before:
                        Color:
                            rgba: 0.3, 0.3, 0.3, 1
                        Rectangle:
                            pos: self.pos
                            size: self.size

        RV

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

标签: pythonkivy

解决方案


一些奇怪的类构造,但假设这是其他考虑的结果,您可以通过进行一些更改来使其工作。由于我没有看到任何实例Scanner,因此您可以将change_number()方法更改为静态方法(因此您不需要实例),如下所示:

class Scanner():
    def __init__(self, **kwargs):
        super(Scanner, self).__init__(**kwargs)
        print("Scanner Init Done")

    @staticmethod
    def change_number():
        # here excluded is some magic function generating numbers
        name_list = ['adam', 'peter', 'christine', 'lisa']
        number_list = ['1923', '1924', '1925', '1929']
        App.get_running_app().root.get_screen('MainScreen').ids.rv.update_list(name_list, number_list)

上面的最后一行只是在你的显示器中获取实例的一种方法RV,但它需要在你的“kv”文件的规则中设置id你的实例:RV<MainScreen>

    RV:
        id: rv

请注意,id在:

<RV>:
    id: Hostlist

没用。

并且MainScreen类稍作更改以调用新的静态方法:

class MainScreen(Screen):

    def update(self):
        Scanner.change_number()

推荐阅读