如何在 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_helper
中 kv
规则的好处(因为 screen_helper
尚未加载)。
然后,您的 build()
方法 returns 使用 Builder
构建的 GUI 结果,sm
将被忽略。因此,虽然 sm
是 ScreenManager
,但它并不是您的应用程序实际使用的那个(它使用的是 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'))
我在 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_helper
中 kv
规则的好处(因为 screen_helper
尚未加载)。
然后,您的 build()
方法 returns 使用 Builder
构建的 GUI 结果,sm
将被忽略。因此,虽然 sm
是 ScreenManager
,但它并不是您的应用程序实际使用的那个(它使用的是 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'))