Как в Python + Kivy сделать каждое окно отдельным KV файлом?
Результаты поиска в гугле не дали ответа. Поэтому надеюсь ответят тут.
Есть простой код Python + Kivy для переключения между окнами.
Файл .py
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.button import Button
from kivy.uix.screenmanager import ScreenManager, Screen
class MenuScreen(Screen):
pass
class SettingsScreen(Screen):
pass
class ScreenManager(ScreenManager):
pass
kv = Builder.load_file("Test.kv")
class TestApp(App):
def build(self):
return kv
TestApp().run()
файл Test.kv
ScreenManager:
MenuScreen:
SettingsScreen
<MenuScreen>:
name: 'menu'
BoxLayout:
Button:
text: 'Goto settings'
on_press:
root.manager.transition.direction = 'left'
root.manager.current = 'settings'
Button:
text: 'Quit'
<SettingsScreen>:
name: 'settings'
BoxLayout:
Button:
text: 'My settings button'
Button:
text: 'Back to menu'
on_press:
root.manager.transition.direction = 'left'
root.manager.current = 'menu'
Но предположим, что у меня приложение где 100 разных окон с такими кнопками, в каждом окне свой определенный независимый текст и кнопки ссылаются (в смысле on_press) на окна вразброс (например, в окне номер 1 кнопки ссылаются на окно номер 4 и номер 18; в окне номер 2 кнопки ссылаются на окно номер 7 и 21 и т.д.).
Понятно (либо я не знаю иного варианта), что в файле .py доведется под каждое такое окно создать свой класс.
Но файл .kv может получиться на тысячи строк. А если вдруг в определенном одном-двух окнах нужно внести изменения - не удобно потом копаться по всему файлу.
Можно ли сделать так, чтобы каждое окно было отдельным .kv файлом и если да, то как реализовать?
Догадываюсь, что с применением #: include и даже пробовал. Но проблема появляется на уровне on_press на кнопке, т.к. вариант root.manager.current ей не нравится, а другие не нашел.
Ответы (1 шт):
Пример кода множества форм, с доступом к ним.
def build(self):
return self.load_widgets()
def load_widgets(self):
self.sm = ScreenManager()
self.sm.add_widget(Builder.load_file("ui/kv1.kv"))
self.sm.add_widget(Builder.load_file("ui/kv2.kv"))
self.sm.add_widget(Builder.load_file("ui/kv3.kv"))
self.sm.add_widget(Builder.load_file("ui/kv4.kv"))
self.sm.add_widget(Builder.load_file("ui/kv5.kv"))
return self.sm
def set_kv1(self, *args):
self.sm.current = "kv1"
def get_kv1(self):
self.sm.get_screen('kv1')
Доступ из kv к функциям приложения, ну и соответственно в другие kv можно залезть.
<ItemListLock@TwoLineAvatarIconListItem>
id: my_id
icon: ""
font_style: "Caption"
secondary_font_style: "Caption"
on_release:
app.set_kv1(self); # передаем "self" указатель на эту форму
app.get_kv1().ids.icon = "door"; # так получаем доступ к элементам формы.