2

I once managed to get a multi-screen program working by having everything (including screens) defined in a single .kv file.

By using root.current (in .kv file) or self.root.current (in Python file) I was able to switch between screens. However, the .kv file grows very large and hard to maintain once there are several screens with many widgets.

This time I tried to define Screens in separate .kv files, but I can't get switching between screens to work. Every attempt so far resulted in an error (invalid syntax, screen name not defined...).

Is there a way (or ways) to switch between screens, defined in separate .kv files? Here are the files I am using:

main.py

from kivy.app import App


class MainApp(App):
    pass


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

main.kv:

#:include screen_1.kv
#:include screen_2.kv

#:import NoTransition kivy.uix.screenmanager.NoTransition

ScreenManager:
    transition: NoTransition()


    Screen:
        name: "main_screen"

        BoxLayout:
            orientation: "vertical"

            Label:
                text: "main screen"
            Button:
                text: "to screen 1"
                on_press: app.root.current = "screen_1"
            Button:
                text: "to screen 2"
                on_press: app.root.current = "screen_2"

screen_1.kv:

Screen:
    name: 'screen_1'

    BoxLayout:
        orientation: "vertical"

        Label:
            text: "Screen 1"
        Button:
            text: "to main screen"
            on_press: app.root.current = "main_screen"
        Button:
            text: "to screen 2"
            on_press: app.root.current = "screen_2"

screen_2.kv:

Screen:
    name: 'screen_2'

    BoxLayout:
        orientation: "vertical"

        Label:
            text: "Screen 2"
        Button:
            text: "to main screen"
            on_press: app.root.current = "main_screen"
        Button:
            text: "to screen 1"
            on_press: app.root.current = "screen_1"
James C
  • 901
  • 1
  • 18
  • 38

1 Answers1

3

Solution

  1. Add dynamic class into screen_1.kv and screen_2.kv, e.g. <Screen1@Screen>: and <Screen2@Screen>: respectively.
  2. Instantiate screens, Screen1: and Screen2: in main.kv

Example

screen_1.kv

<Screen1@Screen>:
    name: 'screen_1'

    BoxLayout:
        orientation: "vertical"

        Label:
            text: "Screen 1"
        Button:
            text: "to main screen"
            on_press: app.root.current = "main_screen"
        Button:
            text: "to screen 2"
            on_press: app.root.current = "screen_2"

screen_2.kv

<Screen2@Screen>:
    name: 'screen_2'

    BoxLayout:
        orientation: "vertical"

        Label:
            text: "Screen 2"
        Button:
            text: "to main screen"
            on_press: app.root.current = "main_screen"
        Button:
            text: "to screen 1"
            on_press: app.root.current = "screen_1"

main.kv

#:include screen_1.kv
#:include screen_2.kv

#:import NoTransition kivy.uix.screenmanager.NoTransition


ScreenManager:
    transition: NoTransition()


    Screen:
        name: "main_screen"

        BoxLayout:
            orientation: "vertical"

            Label:
                text: "main screen"
            Button:
                text: "to screen 1"
                on_press: app.root.current = "screen_1"
            Button:
                text: "to screen 2"
                on_press: app.root.current = "screen_2"

    Screen1:

    Screen2:

Output

Img01 - Main Screen Img02 - Screen1 Img03 - Screen2

ikolim
  • 15,721
  • 2
  • 19
  • 29
  • Thank you, this solution works. For future reference, could you please hint me the resource/docs, where this techniquie is explained. So I will understand how it works and be able to find solution to similar problems on my own next time. Thanks. – James C Jul 23 '18 at 20:00
  • You are most welcome. Updated post with link for [Kivy Dynamic Classes](https://kivy.org/docs/guide/lang.html#dynamic-classes). Noted. – ikolim Jul 23 '18 at 22:48
  • I believe I have done so, or it does not appear that way for some reason? – James C Jul 29 '18 at 09:54