Kivy(Python)中使用ScreenManager实现多页面跳转求助
Kivy多页面跳转解决方案
核心问题在于你原本的两个页面是独立的MDApp实例,无法直接实现跳转。正确的做法是用ScreenManager(这里用KivyMD的MDScreenManager更适配)统一管理所有页面,所有页面作为Screen的子元素,由同一个主App控制。
以下是整合后的完整代码:
from kivy.core.text import LabelBase from kivy.lang import Builder from kivy.core.window import Window from kivy.factory import Factory from kivy.uix.image import Image from kivymd.app import MDApp from kivymd.uix.screenmanager import MDScreenManager from kivymd.uix.list import IRightBodyTouch, ILeftBody from kivymd.uix.selectioncontrol import MDCheckbox Window.size = (350, 580) # 登录页面KV代码 login_kv = """ <LoginScreen@Screen>: md_bg_color: 0, 0, 0, 1 Image: source: "img\\logo5.png" pos_hint: {"center_x": .5, "center_y": .85} size_hint: .18, .18 MDFloatLayout: size_hint: .9, .07 pos_hint: {"center_x": .5, "center_y": .68} canvas: Color: rgb: 250/255, 250/255, 250/255, 1 RoundedRectangle: size: self.size pos:self.pos radius: [4] canvas.before: Color: rgb: 217/255, 217/255, 217/255, 1 Line: width: 1.1 rounded_rectangle: self.x, self.y, self.width, self.height, 4, 4, 4, 4, 100 TextInput: hint_text: "Phone number, username or e-mail" size_hint: 1, None pos_hint: {"center_x": .5, "center_y": .5} height: self.minimum_height background_color: 1, 1, 1, 0 font_size: "14sp" font_name: "MRoboto" hint_text_color: 170/255, 170/255, 170/255, 1 padding: 13 cursor_color: 0, 0, 0, 1 MDFloatLayout: size_hint: .9, .07 pos_hint: {"center_x": .5, "center_y": .59} canvas: Color: rgb: 250/255, 250/255, 250/255, 1 RoundedRectangle: size: self.size pos:self.pos radius: [4] canvas.before: Color: rgb: 217/255, 217/255, 217/255, 1 Line: width: 1.1 rounded_rectangle: self.x, self.y, self.width, self.height, 4, 4, 4, 4, 100 TextInput: id: password hint_text: "Password" size_hint: 1, None pos_hint: {"center_x": .5, "center_y": .5} height: self.minimum_height background_color: 1, 1, 1, 0 font_size: "14sp" font_name: "MRoboto" password: True hint_text_color: 170/255, 170/255, 170/255, 1 padding: 13 cursor_color: 0, 0, 0, 1 Button: text: "Log in" color: 1, 1, 1, 1 size_hint: .9, .07 pos_hint: {"center_x": .5, "center_y": .43} background_color: 1, 1, 1, 0 font_size: "13sp" font_name: "BRoboto" canvas.before: Color: rgb: 98/255, 170/255, 243/255, 1 RoundedRectangle: size: self.size pos: self.pos radius: [4] on_press: app.root.current = "lists" MDLabel: text: "Don't have an account?" color: 172/255, 172/255, 172/255, 1 pos_hint: {"center_x": .74, "center_y": .095} font_size: "13sp" font_name: "MRoboto" MDTextButton: text: "Sign up" color: 98/255, 170/255, 243/255, 1 pos_hint: {"center_x": .685, "center_y": .095} font_size: "13sp" font_name: "MRoboto" MDCheckbox: size_hint: None, None size: "48dp", "48dp" pos_hint: {"center_x": .1, "center_y": .34} on_active: app.show_password(*args) MDLabel: id: password_text text: "Show Password" pos_hint: {"center_x": .43, "center_y": .34} """ # 列表页面KV代码 list_kv = """ <ListItemWithCheckbox@OneLineAvatarIconListItem>: MyAvatar: source: "data/logo/kivy-icon-128.png" MyCheckbox: <ListScreen@Screen>: name: "lists" BoxLayout: orientation: "vertical" MDTopAppBar: title:"Hide the story to:" md_bg_color: app.theme_cls.primary_color elevation: 3 ScrollView: MDList: id: scroll """ Builder.load_string(login_kv) Builder.load_string(list_kv) class MyCheckbox(IRightBodyTouch, MDCheckbox): pass class MyAvatar(ILeftBody, Image): pass class MainApp(MDApp): def build(self): # 初始化屏幕管理器 sm = MDScreenManager() # 添加登录页面 login_screen = Factory.LoginScreen(name="login") sm.add_widget(login_screen) # 添加列表页面并填充数据 list_screen = Factory.ListScreen(name="lists") for i in range(30): list_screen.ids.scroll.add_widget(Factory.ListItemWithCheckbox(text=f"Item {i}")) sm.add_widget(list_screen) # 默认显示登录页 sm.current = "login" return sm def show_password(self, checkbox, value): # 获取登录页实例并切换密码显示状态 login_screen = self.root.get_screen("login") if value: login_screen.ids.password.password = False login_screen.ids.password_text.text = "Hide Password" else: login_screen.ids.password.password = True login_screen.ids.password_text.text = "Show Password" if __name__ == "__main__": LabelBase.register(name="BRoboto", fn_regular="font\\Roboto-Bold.ttf") LabelBase.register(name="MRoboto", fn_regular="font\\Roboto-Medium.ttf") MainApp().run()
关键修改点说明
- 统一App实例:将两个独立的
MDApp合并为一个MainApp,用MDScreenManager管理所有页面 - 页面封装为Screen:把登录页和列表页分别封装成
LoginScreen和ListScreen,每个页面指定唯一name用于跳转 - 跳转逻辑绑定:给登录按钮添加
on_press事件,通过app.root.current = "lists"切换到列表页 - 修复组件问题:给密码输入框添加
id: password,修正password属性值为布尔类型,调整了复选框和标签的位置参数 - 跨页面组件操作:修改
show_password方法,通过get_screen获取登录页实例后操作内部组件
运行时确保图片、字体等资源路径正确,执行main.py即可实现点击登录按钮跳转到列表页的功能。
内容的提问来源于stack exchange,提问作者Henry
相关产品推荐
相关产品推荐

