如何在 Kivy 中更改当前屏幕

How to change current screen in Kivy

我在 Kivy 中使用屏幕管理器,但出于某种原因,它不允许我使用 screenManager.current 方法更改当前屏幕。

from kivymd.app import MDApp
from kivymd.uix.list import MDList, TwoLineListItem
from kivy.uix.scrollview import ScrollView
from kivy.core.window import Window
from kivymd.uix.button import MDFloatingActionButton, MDRectangleFlatButton
from kivymd.uix.textfield import MDTextField
from kivy.lang import Builder
from kivy.uix.screenmanager import Screen, ScreenManager


screen_helper = """
ScreenManager:
    LoginScreen:
        id: login_scr
    ListScreen:
        id: list_scr

<LoginScreen>:
    name: 'login'
    MDTextField:
        id: email
        hint_text: "Email"
        pos_hint: {'center_x':0.5, 'center_y':0.6}
    MDTextField:
        id: password
        hint_text: "Password"
        password: True
        pos_hint: {'center_x':0.5, 'center_y':0.5}
    MDRectangleFlatButton:
        text: 'Login'
        id: login
        pos_hint: {'center_x':0.25, 'center_y':0.4}
        on_press: app.login()
    MDRectangleFlatButton:
        id: account
        text: 'Create Account'
        pos_hint: {'center_x':0.75, 'center_y':0.4}
        on_press: app.create_account()

<ListScreen>:
    name: 'list'
    ScrollView:
        MDList:
            id: assignmentList
    MDFloatingActionButton:
        icon: 'plus'
        pos_hint: {'center_x':0.9, 'center_y':0.05}
        on_press: root.manager.current = 'assignment'
    MDFloatingActionButton:
        icon: 'theme-light-dark'
        pos_hint: {'center_x':0.1, 'center_y':0.05}
        on_press: app.show_theme_picker()
    MDRectangleFlatButton
        id: sortButton
        pos_hint: {'center_x':0.5, 'center_y':0.05}
        text: "Sorted by: Deadline"
        on_press: app.sort()
"""


class LoginScreen(Screen):
    pass


class ListScreen(Screen):
    pass


sm = ScreenManager()
sm.add_widget(LoginScreen(name='login'))
sm.add_widget(ListScreen(name='list'))


class AssignmentTracker(MDApp):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

    def build(self):
        self.theme_cls.theme_style = "Dark"
        screen = Builder.load_string(screen_helper)
        return screen

    def login(self):
        print(sm.current_screen)
        sm.current = 'list'

Window.size = (350, 700)
AssignmentTracker().run()

出于某种原因 sm.current = 'list' 更改了屏幕,再次按登录按钮可以看到,因为 sm.current_screen 将其输出为列表屏幕,但显示的屏幕不会变化

您的代码的主要问题是您构建了两次 GUI。代码:

    screen = Builder.load_string(screen_helper)

使用 screen_helper 字符串中的 kv 规则构建 GUI。和代码:

sm = ScreenManager()
sm.add_widget(LoginScreen(name='login'))
sm.add_widget(ListScreen(name='list'))

也构建了 GUI,但没有 screen_helperkv 规则的好处(因为 screen_helper 尚未加载)。

然后,您的 build() 方法 returns 使用 Builder 构建的 GUI 结果,sm 将被忽略。因此,虽然 smScreenManager,但它并不是您的应用程序实际使用的那个(它使用的是 screen)。

因此,您的 login() 方法对 sm 进行了更改,这不是您应用程序的一部分。修复只是将 login() 更改为引用正确的 ScreenManager:

def login(self):
    print(self.root.current_screen)
    self.root.current = 'list'

您可以删除以下行:

sm = ScreenManager()
sm.add_widget(LoginScreen(name='login'))
sm.add_widget(ListScreen(name='list'))