Kivy Python Recycleview Обновление на Buttonpress - PullRequest
0 голосов
/ 22 декабря 2019

Я хочу сделать повторный просмотр в моем коде видимым после нажатия кнопки Обновить. После повторного нажатия этой кнопки список должен обновиться с учетом новых данных. Проблема в том, что кнопка «Обновить» не работает таким образом.

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

Если я записываю данные непосредственно при запуске, я вижу некоторый вывод, поэтому я предполагаю, что основная проблема заключается в том, что recycleview не обновляется (о чем я много читал, но не могу понять).

main 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()

test.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()

1 Ответ

0 голосов
/ 23 декабря 2019

Некоторая странная конструкция класса, но предполагая, что это результат других соображений, вы можете заставить ее работать, внеся несколько изменений. Поскольку я не вижу ни одного экземпляра 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, который находится на вашем дисплее, но он требует установки id вашего RV в правиле <MainScreen> вашего файла 'kv':

    RV:
        id: rv

Обратите внимание, что id in:

<RV>:
    id: Hostlist

бесполезен.

И класс MainScreen немного изменяется, вызывая новый статический метод:

class MainScreen(Screen):

    def update(self):
        Scanner.change_number()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...