python-3.xkivy

Create kivy app by multiple .kv files and .py files


My files:

  1. main.py - main.kv
  2. login.py - login.kv
  3. workarea.py - workarea.kv
  4. welcome.py - welcom.kv

How to open welcome.kv with the push of a button made in main.py and main.kv?

I want to not put all the interface code in one main.kv file.

main.py:

from login import Login
from welcome import Welcome

    class Screen_manager(ScreenManager):
        def __init__(self,**kwargs):
            super(ScreenManager,self).__init__(**kwargs)
            self.current='login-page'# not screen by name 'login-page' error
            self.addWidget(Login(name='login-page') #'nonetype' object has no attribute 'stop'


    class MainApp(App):
        Build(self):
            return ScreenManager()

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

login.py:

from kivy.uix.screenmanger import Screen
    class Login(Screen):
        def openwelcome(self):
            ?????

login.kv:

<Login>:
    name:login-page
    Button:
        text:"press me"
        on_press:root.openwelcome()

Solution

  • In order to work with multiple .kv & .py files, lets assume we have all the .py file in libs/baseclass & all the .kv files in libs/kvs. In order to integrate all the files, we can create a main.kv file whose content looks like below:

    #  import the python files defining the Screens
    #: import Screen1 libs.baseclass.screen1.Screen1
    #: import Screen2 libs.baseclass.screen2.Screen2
    
    #  include the kv files for the other Screens
    #: include libs/kvs/screen1.kv
    #: include libs/kvs/screen2.kv
    
    ScreenManager:
        Screen1:
        Screen2:
    
    

    Finally load this file through Builder in an App. To link different screens, let's assume you are currently on Screen1 and want to go to Screen2, create your screen1.kv & screen2.kv as below:

    <Screen1>:
        name: 'Screen1'
    
    # And in screen2.kv file
    
    <Screen2>:
        name: 'Screen2'
    

    Finally on your main.kv should look like this

    ScreenManager:
        Screen:
            name: "main_screen"
    
            BoxLayout:
                orientation: "vertical"
    
                Label:
                    text: "main screen"
                Button:
                    text: "to screen 1"
                    on_press: app.root.current = "Screen1"
                Button:
                    text: "to screen 2"
                    on_press: app.root.current = "Screen2"
        Screen1:
        Screen2: