Как в 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 шт):

Автор решения: Jessy James

Пример кода множества форм, с доступом к ним.

    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"; # так получаем доступ к элементам формы.
→ Ссылка