KivyMD点击MDList项切换屏幕无效及传递数据的咨询
问题修复方案
一、点击列表项无法跳转的解决
错误原因
你当前代码存在两个核心问题导致跳转失效:
- py文件中全局定义的
ScreenManager实例sm完全没有被使用,build方法直接返回KV文件中定义的顶层MDBoxLayout,因此app.root是布局组件,不存在current属性,调用app.root.current自然无效 - KV文件中定义的
<Manager>规则仅声明了组件模板,没有被实际实例化,你自定义的Device屏幕根本没有加入到实际渲染的组件树中
修复步骤
- 调整根组件结构,将
ScreenManager作为根部件,把原有带底部导航的界面作为第一个主屏幕 - 新增专门的详情屏幕用于接收列表项传递的参数
修改后的main.py代码:
from kivy.lang import Builder from kivymd.uix.screen import Screen from kivy.uix.screenmanager import ScreenManager from kivymd.app import MDApp from kivymd.uix.list import MDList, ThreeLineAvatarIconListItem from kasa import Discover from decimal import Decimal import asyncio # 主屏幕(含底部导航) class MainScreen(Screen): pass # 详情屏幕 class DeviceDetailScreen(Screen): # 自定义属性用于接收传递的参数 device_info = {} sm = ScreenManager() sm.add_widget(MainScreen(name='main_screen')) sm.add_widget(DeviceDetailScreen(name='device_detail')) class Test(MDApp): def build(self): return Builder.load_file('app.kv') def on_start(self): devices = asyncio.run(Discover.discover()) for addr, dev in devices.items(): asyncio.run(dev.update()) # 给列表项绑定点击事件,传递当前设备信息 item = ThreeLineAvatarIconListItem( text=dev.alias, secondary_text="Current Power: %.2f" % Decimal(dev.emeter_realtime['power_mw'] / 10) + " mW", tertiary_text="Current Runtime: " + dev.on_since.strftime("%H:%M:%S"), on_release=lambda x, dev=dev: self.go_to_detail(dev) ) self.root.get_screen('main_screen').ids.devices.add_widget(item) # 跳转+传参统一方法 def go_to_detail(self, dev): # 获取目标屏幕实例 detail_screen = self.root.get_screen('device_detail') # 传递参数到目标屏幕 detail_screen.device_info = { 'alias': dev.alias, 'power': "%.2f mW" % Decimal(dev.emeter_realtime['power_mw'] / 10), 'runtime': dev.on_since.strftime("%H:%M:%S") } # 更新详情页展示内容 detail_screen.ids.info_label.text = f"设备名称:{detail_screen.device_info['alias']}\n当前功率:{detail_screen.device_info['power']}\n运行时长:{detail_screen.device_info['runtime']}" # 执行跳转 self.root.current = 'device_detail' # 返回主屏幕方法 def go_back(self): self.root.current = 'main_screen' Test().run()
修改后的app.kv代码:
#: import SlideTransition kivy.uix.screenmanager.SlideTransition <MainScreen>: name: 'main_screen' MDBoxLayout: orientation:'vertical' MDToolbar: title: 'SaveSmart' md_bg_color: .2, .2, .2, 1 MDBottomNavigation: panel_color: .2, .2, .2, 1 MDBottomNavigationItem: name: 'screen 4' text: 'Dashboard' GridLayout: id: readings cols: 2 MDBottomNavigationItem: name: 'screen 3' text: 'Devices' ScrollView: MDList: id: devices MDBottomNavigationItem: name: 'screen 1' text: 'Predictions' ScrollView: MDList: OneLineListItem: text: "Predictions go here!" on_release: app.root.current = 'device_detail' MDBottomNavigationItem: name: 'screen 2' text: 'Recommendations' MDLabel: text: 'Recommendations' halign:'center' <DeviceDetailScreen>: name: 'device_detail' MDBoxLayout: orientation: 'vertical' MDToolbar: title: '详情页' md_bg_color: .2, .2, .2, 1 left_action_items: [["arrow-left", lambda x: app.go_back()]] MDLabel: id: info_label halign: 'center'
二、列表项信息传递实现
参数传递逻辑非常简单,按以下步骤操作即可:
- 给动态生成的列表项绑定
on_release事件时,通过lambda表达式将当前列表对应的业务数据作为参数传入跳转方法 - 在跳转方法中直接给目标屏幕的自定义属性赋值,即可完成参数传递
- 目标屏幕拿到参数后直接更新对应组件的显示内容即可
内容的提问来源于stack exchange,提问作者MohammadAlshamsi
相关产品推荐
相关产品推荐

