KivyMD: доступ к идентификатору ярлыка из класса экрана

Я использую KivyMD и хочу обновить данные на втором экране с помощью метода on_pre_enter. Я безуспешно пытаюсь получить доступ к идентификатору метки из метода класса экрана "on_pre_enter".

Я могу получить доступ к идентификатору метки из класса "MainApp", но не могу получить доступ к нему из класса "Second_Screen".

MainApp.py

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


class MainApp(MDApp):
    def __init__(self, **kwargs):
        self.title = "My Material Application"
        self.theme_cls.primary_palette = "Blue"
        super().__init__(**kwargs)

    def on_start(self):
        self.root.ids.main_screen_label.text = "Main Screen Updated"

    def build(self):
        self.root = Builder.load_file("app.kv")


class Second_Screen(Screen):
    def on_pre_enter(self):
        MainApp.ids.second_screen_label = "Second Screen Updated"

    pass


if __name__ == "__main__":
    MainApp().run()

App.kv

NavigationLayout:
    MDNavigationDrawer:
        NavigationDrawerSubheader:
            text: "Menu:"

        NavigationDrawerIconButton:
            icon:'battery'
            text: "Main Screen"
            on_release:
                screen_manager.current = "main_screen"

        NavigationDrawerIconButton:
            icon:'battery'
            text: "Second Screen"
            on_release:
                screen_manager.current = "second_screen"


    BoxLayout:
        id: box1
        orientation: 'vertical'
        MDToolbar:
            title: "My App"
            md_bg_color: app.theme_cls.primary_color
            left_action_items:
                [['menu', lambda x: app.root.toggle_nav_drawer()]]

        ScreenManager:
            id: screen_manager
            Screen:
                name: "main_screen"
                BoxLayout:
                    size_hint: .8, .8
                    pos_hint: {"center_x": .5, "center_y": .5}
                    spacing: dp(100)
                    orientation: 'vertical'


                    MDLabel:
                        id: main_screen_label
                        text: "Main Screen Default"

            Second_Screen:
                name: "second_screen"
                FloatLayout:
                    id: float
                    size_hint: .8, .8
                    pos_hint: {"center_x": .5, "center_y": .5}
                    spacing: dp(100)
                    orientation: 'vertical'


                    MDLabel:
                        id: second_screen_label
                        text: "Second Screen Default"

Я также пробовал использовать:

class Second_Screen(Screen):
    def on_pre_enter(self):
        self.ids.second_screen_label.text = "Second Screen Updated"
    pass 

После запуска я получаю следующую ошибку:

   self.ids.second_screen_label.text = "Second Screen Updated"
   File "kivy\properties.pyx", line 863, in 
   kivy.properties.ObservableDict.__getattr__
   AttributeError: 'super' object has no attribute '__getattr__'

Как правильно получить доступ к идентификаторам, определенным в файле KV, из класса экрана?

1 ответ

Решение

Определите макет экрана в отдельном правиле <MyScreen>:

<MyScreen>:
    name: "my_screen"

    FloatLayout:
        # ...

Чтобы добавить этот экран в ScreenManager, просто напишите:

    ScreenManager:
        id: screen_manager

        MyScreen:

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

  • из класса экрана: self.ids.my_id
  • из класса приложения: self.root.ids.screen_manager.get_screen("screen_name").ids.my_id
  • из других виджетов: App.get_running_app()..root.ids.screen_manager.get_screen("screen_name").ids.my_id

Итак, ваш полный код будет:

main.py

from kivy.lang import Builder
from kivymd.app import MDApp
from kivy.uix.screenmanager import Screen


class MainApp(MDApp):
    def __init__(self, **kwargs):
        self.title = "My Material Application"
        self.theme_cls.primary_palette = "Blue"
        super().__init__(**kwargs)

    def build(self):
        self.root = Builder.load_file("app.kv")

    def on_start(self):
        self.root.ids.screen_manager.get_screen(
            "main_screen"
        ).ids.main_screen_label.text = "Main Screen Updated"


class MainScreen(Screen):
    pass


class SecondScreen(Screen):
    def on_pre_enter(self):
        self.ids.second_screen_label.text = "Second Screen Updated"


if __name__ == "__main__":
    MainApp().run()

app.kv

NavigationLayout:
    MDNavigationDrawer:
        NavigationDrawerSubheader:
            text: "Menu:"

        NavigationDrawerIconButton:
            icon: "battery"
            text: "Main Screen"
            on_release:
                screen_manager.current = "main_screen"

        NavigationDrawerIconButton:
            icon: "battery"
            text: "Second Screen"
            on_release:
                screen_manager.current = "second_screen"


    BoxLayout:
        id: box1
        orientation: "vertical"
        MDToolbar:
            title: "My App"
            md_bg_color: app.theme_cls.primary_color
            left_action_items:
                [["menu", lambda x: app.root.toggle_nav_drawer()]]

        ScreenManager:
            id: screen_manager

            MainScreen:
            SecondScreen:

<MainScreen>:
    name: "main_screen"

    BoxLayout:
        size_hint: .8, .8
        pos_hint: {"center_x": .5, "center_y": .5}
        spacing: dp(100)
        orientation: "vertical"

        MDLabel:
            id: main_screen_label
            text: "Main Screen Default"


<SecondScreen>:
    name: "second_screen"

    FloatLayout:
        id: float
        size_hint: .8, .8
        pos_hint: {"center_x": .5, "center_y": .5}
        spacing: dp(100)
        orientation: "vertical"

        MDLabel:
            id: second_screen_label
            text: "Second Screen Default"
Другие вопросы по тегам