如何通过该功能更改屏幕?

How do i change screen through the function?

我有一个应用程序,但如何不通过 kv 而是通过 python 函数来更改屏幕, 有我的 python 代码,我得到一个错误名称 'root' 未定义。尝试做同样的事情,但使用 self,它说 MainApp 没有属性 screen_manager,那么我该如何访问它?

class Main(MDBoxLayout):
    pass
class LoginScreen(Screen):
    pass
class MainApp(MDApp):
    def build(self):
        return Builder.load_file("Main.kv")
    def on_start(self):
        if is_logged():
            self.screen_manager.current="main_screen"
        else:
            self.screen_manager.current="login_screen"

    def is_logged():
        return False

MainApp().run()

这也是我的kv代码

<LoginScreen>:
    id: login_screen
    text: "Login"
    icon: "login"

    MDBoxLayout:
        orientation: "vertical"
        MDLabel:
            text:"Welcome to Plaim"
            font_style:"H4"
            text_color:"0,0,0,1"          
        MDTextField:
            hint_text:"login"
            id: username
            hint_text: "Username"
            required: True
            helper_text_mode: "on_error"
        MDTextField:
            hint_text:"password"
            id: password
            password: True
            hint_text: "Password"
            required: True
            helper_text_mode: "on_error"

        MDRaisedButton:
            text: "Sign In"
            on_release:
                app.change_screen("main_screen")
<Main>:
    orientation: "vertical"
    id: main
    ScreenManager:
        LoginScreen:
            name: "login_screen"
            id: login_screen
        MainScreen:
            name: "main_screen"
            id: main_screen

我创建了最少的工作代码并且我需要

self.root.current = "main_screen"

self.root.ids.screen_manager.current = "main_screen"

main.py

from kivymd.app import MDApp
from kivy.lang import Builder
from kivy.uix.screenmanager import Screen #, ScreenManager
from kivymd.uix.boxlayout import MDBoxLayout

class Main(MDBoxLayout):
    pass
    
class LoginScreen(Screen):
    pass

class MainScreen(Screen):
    pass
    
class MainApp(MDApp):

    def build(self):
        return Builder.load_file("Main.kv")
        
    def on_start(self):
        #print(type(self))
        #print(type(self.root))
        #print(type(self.root.ids))
        #print(type(self.root.ids.screen_manager))

        if is_logged():
            self.root.current = "main_screen"
            #self.root.ids.screen_manager.current = "main_screen"
        else:
            self.root.current = "login_screen"
            #self.root.ids.screen_manager.current = "login_screen"

def is_logged():
    return True

MainApp().run()

Main.kv

Main:
    id: main
    name: "main"
    Button:
        text: "Hello World"
        
    ScreenManager:
        id: screen_manager
        name: "screen_manager"
        
        LoginScreen:
        MainScreen:

<LoginScreen>:
    id: login_screen
    name: "login_screen"
    
    text: "Login"
    icon: "login"
    MDBoxLayout:
        orientation: "vertical"
        MDLabel:
            text:"Welcome to Plaim"
            font_style:"H4"
            text_color:"0,0,0,1"          
        MDTextField:
            hint_text:"login"
            id: username
            hint_text: "Username"
            required: True
            helper_text_mode: "on_error"
        MDTextField:
            hint_text:"password"
            id: password
            password: True
            hint_text: "Password"
            required: True
            helper_text_mode: "on_error"

        MDRaisedButton:
            text: "Sign In"
            on_release:
                root.manager.current = "main_screen"
                root.manager.transition.direction = "left"
                
<MainScreen>:
    id: main_screen
    name: "main_screen"
    
    orientation: "vertical"
    Button:
        text: "LOGIN"
        on_release:
            root.manager.current = "login_screen"
            root.manager.transition.direction = "right"

顺便说一句:

如果我使用小写名称 main.kv 那么我不需要

 return Builder.load_file("Main.kv")

但我可以使用

 return Main()

它会自动加载 main.kv

但在 main.kv 中我必须使用 <Main>: 而不是 Main:


main.py

from kivymd.app import MDApp
from kivy.uix.screenmanager import Screen #, ScreenManager
from kivymd.uix.boxlayout import MDBoxLayout

class Main(MDBoxLayout):
    pass
    
class LoginScreen(Screen):
    pass

class MainScreen(Screen):
    pass
    
class MainApp(MDApp):

    def build(self):
        return Main()
        
    def on_start(self):
        #print(type(self))
        #print(type(self.root))
        #print(type(self.root.ids))
        #print(type(self.root.ids.screen_manager))

        if is_logged():
            self.root.current = "main_screen"
            #self.root.ids.screen_manager.current = "main_screen"
        else:
            self.root.current = "login_screen"
            #self.root.ids.screen_manager.current = "login_screen"

def is_logged():
    return True

MainApp().run()

main.kv(小写名称)

<Main>:
    id: main
    name: "main"
    Button:
        text: "Hello World"
        
    ScreenManager:
        id: screen_manager
        name: "screen_manager"
        
        LoginScreen:
        MainScreen:

<LoginScreen>:
    id: login_screen
    name: "login_screen"
    
    text: "Login"
    icon: "login"
    MDBoxLayout:
        orientation: "vertical"
        MDLabel:
            text:"Welcome to Plaim"
            font_style:"H4"
            text_color:"0,0,0,1"          
        MDTextField:
            hint_text:"login"
            id: username
            hint_text: "Username"
            required: True
            helper_text_mode: "on_error"
        MDTextField:
            hint_text:"password"
            id: password
            password: True
            hint_text: "Password"
            required: True
            helper_text_mode: "on_error"

        MDRaisedButton:
            text: "Sign In"
            on_release:
                root.manager.current = "main_screen"
                root.manager.transition.direction = "left"
                
<MainScreen>:
    id: main_screen
    name: "main_screen"
    
    orientation: "vertical"
    Button:
        text: "LOGIN"
        on_release:
            root.manager.current = "login_screen"
            root.manager.transition.direction = "right"