how to switch between two screens in kivy python?

512 Views Asked by At

I'm trying to switch between two screens.. but it doesn't work.. it didn't show anything or any error I don't know what is the problem, here's my code

from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen


class mainWindow(Screen):
    pass


class secondWindow(Screen):
    pass


class windowManager(ScreenManager):
    pass

sm = ScreenManager()
sm.add_widget(mainWindow(name='main'))
sm.add_widget(secondWindow(name='second'))


class multApp(App):
    def build(self):
        return mainWindow()


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

and mult.kv

windowManager:
    mainWindow:
    secondWindow:

<mainWindow>:
    name: "main"

    Button:
        text: "Submit"
        on_press : root.manager.current = "second"

<secondWindow>:
    name: "second"

    Button:
        text: "go back"
        on_press : root.manager.current = "main"
2

There are 2 best solutions below

0
John Anderson On

You have several issues in your code.

  • Your build() method returns mainWindow(). This means that your app GUI consists of just a Screen (mainwindow) with no ScreenManager. So the root.manager.current = lines in your kv will fail because there is no manager.
  • Your mult.kv file contains a rule (windowManager:) for building the GUI, but this rule is over-ridden by your build() method.
  • In your code, you have three lines (starting with sm = ScreenManager()) that also build the GUI, but you do nothing with the results of these lines. So those lines have no effect.
  • Your class names should start with an upper case character. When using kv, as you are, this is a requirement.

Taking all this into account, here is a modified version of your code that should work:

python code:

from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen

class MainWindow(Screen):
    pass


class SecondWindow(Screen):
    pass


class WindowManager(ScreenManager):
    pass

# sm = ScreenManager()
# sm.add_widget(mainWindow(name='main'))
# sm.add_widget(secondWindow(name='second'))


class multApp(App):
    pass
    # def build(self):
    #     return mainWindow()


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

mult.kv:

WindowManager:
    MainWindow:
    SecondWindow:

<MainWindow>:
    name: "main"

    Button:
        text: "Submit"
        on_press : root.manager.current = "second"

<SecondWindow>:
    name: "second"

    Button:
        text: "go back"
        on_press : root.manager.current = "main"
0
Foton On

I agree with John's answers, just to add to that. If you are declaring manager as a class I always return manager in the build methods, also its good practice to create ids for your screens under your root manager, as such will make them easier to reference

<WindowManager>:
    id: screen_manager

    MainWindow:

         id: main_window
         name: "main_window"
         manager: screen_manager   

    SecondWindow:

         id: second_window
         name: "second_window"
         manager: screen_manager