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"