Search code examples
pythonandroidkivykivy-language

Error Code : "KivyMD: App object must be initialized before loading "


I am receiving the Error : "KivyMD: App object must be initialized before loading " when I am trying to add a kivymd button (MDRaisedButton).

I tried debugging, the issue is when I add the BoxLayout under the DateScreen, I just don't find any information on how to fix it.

How should one initialized app object before loading ?

import kivy
kivy.require("1.11.1")
from kivy.app import App
from kivy.lang import Builder
from kivy.clock import Clock
from kivy.uix.screenmanager import Screen
from kivymd.theming import ThemeManager


class WelcomeScreen(Screen):  # Defines WelcomeScreen instance as a screen widget.
    pass

class DateScreen(Screen):  # Defines DateScreen instance as a screen widget.
    pass

class ResultScreen(Screen):  # Defines ResultScreen instance as a screen widget.
    pass

root_widget = Builder.load_string("""
ScreenManager:
    WelcomeScreen:
    DateScreen:
    ResultScreen:
<WelcomeScreen>:
    _welcome_screen_text_: welcome_screen
    name: 'my_welcome_screen'
    Label:
        id: welcome_screen
        Image: 
            source: 'Cheers.jpg'
            size: 200, 200
            center: self.parent.center

<DateScreen>:
    _date_screen_text_: date_screen
    name: 'my_date_screen'
    Label:
        id: date_screen
        text: "This is the date selection screen"
    BoxLayout:
        size_hint: 0.1, 0.5
        pos_hint: {'center_x': 0.5, 'center_y': 0.5}
        MDRaisedButton:
            text: 'MDButton1'
<ResultScreen>:
    _result_screen_text_: result_screen
    name: 'my_result_screen'
    Label:
        id: result_screen
        text: "This is where the result will be displayed"
""")

class MainApp(App):

    theme_cls = ThemeManager()

    def build(self):
        self.theme_cls.theme_style = "Dark"
        Clock.schedule_once(self.screen_switch_one, 36)  # clock callback for the first screen
        Clock.schedule_once(self.screen_switch_two, 4)  # clock callback for the second screen
        return root_widget


    def screen_switch_one(a, b):
        root_widget.current = 'my_welcome_screen'  

    def screen_switch_two(a, b):
        root_widget.current = 'my_date_screen' 

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

Please help!


Solution

  • I believe you need to call Builder after the App is initialized (as mentioned in your error). To do that you can save your kv in a string, then call Builder inside the build() method. Like this:

    import kivy
    from kivymd.app import MDApp
    
    kivy.require("1.11.1")
    from kivy.lang import Builder
    from kivy.clock import Clock
    from kivy.uix.screenmanager import Screen
    
    
    class WelcomeScreen(Screen):  # Defines WelcomeScreen instance as a screen widget.
        pass
    
    class DateScreen(Screen):  # Defines DateScreen instance as a screen widget.
        pass
    
    class ResultScreen(Screen):  # Defines ResultScreen instance as a screen widget.
        pass
    
    kv = """
    ScreenManager:
        WelcomeScreen:
        DateScreen:
        ResultScreen:
    <WelcomeScreen>:
        _welcome_screen_text_: welcome_screen
        name: 'my_welcome_screen'
        Label:
            id: welcome_screen
            Image: 
                source: 'Cheers.jpg'
                size: 200, 200
                center: self.parent.center
    
    <DateScreen>:
        _date_screen_text_: date_screen
        name: 'my_date_screen'
        Label:
            id: date_screen
            text: "This is the date selection screen"
        BoxLayout:
            size_hint: 0.1, 0.5
            pos_hint: {'center_x': 0.5, 'center_y': 0.5}
            MDRaisedButton:
                text: 'MDButton1'
    <ResultScreen>:
        _result_screen_text_: result_screen
        name: 'my_result_screen'
        Label:
            id: result_screen
            text: "This is where the result will be displayed"
    """
    
    
    class MainApp(MDApp):
    
        def build(self):
            self.theme_cls.theme_style = "Dark"
            self.root_widget = Builder.load_string(kv)
            Clock.schedule_once(self.screen_switch_one, 36)  # clock callback for the first screen
            Clock.schedule_once(self.screen_switch_two, 4)  # clock callback for the second screen
            return self.root_widget
    
    
        def screen_switch_one(self, dt):
            self.root_widget.current = 'my_welcome_screen'
    
        def screen_switch_two(self, dt):
            self.root_widget.current = 'my_date_screen'
    
    if __name__ == '__main__':
        MainApp().run()