KivyMD中ScreenManager配置NavigationDrawer报AssertionError问题求助
错误原因
- 核心触发
AssertionError的原因是KV规则出现递归自引用:你在<ContentNavigationDrawer>的规则定义内部,又实例化了ContentNavigationDrawer组件,导致Kivy的Builder重复加载同一条规则,触发了规则不允许重复的断言校验。 - 同时存在多处逻辑错误:
ContentNavigationDrawer是抽屉的内容组件,不需要继承Screen,也不需要作为屏幕加到外层ScreenManager中- 你在Python代码中手动创建的
smScreenManager完全没有被使用,属于冗余代码 ContentNavigationDrawer的KV规则里同时写了抽屉列表和主屏幕布局,结构完全混乱,导航相关的布局应该放在外层,而不是抽屉内容组件内部
修复后完整可运行代码
from kivymd.app import MDApp from kivy.lang.builder import Builder from kivy.uix.screenmanager import ScreenManager, Screen from kivy.properties import ObjectProperty from kivy.uix.boxlayout import BoxLayout screen_helper = """ NavigationLayout: ScreenManager: id: main_sm MenuScreen: ProfileScreen: UploadScreen: MDNavigationDrawer: id: nav_drawer ContentNavigationDrawer: screen_manager: main_sm nav_drawer: nav_drawer <MenuScreen>: name: 'menu' MDToolbar: id: toolbar pos_hint: {"top": 1} elevation: 10 title: "菜单页" left_action_items: [["menu", lambda x: nav_drawer.set_state("open")]] MDRectangleFlatButton: text: 'Profile' pos_hint: {'center_x':0.5,'center_y':0.6} on_press: root.manager.current = 'profile' MDRectangleFlatButton: text: 'Upload' pos_hint: {'center_x':0.5,'center_y':0.5} on_press: root.manager.current = 'upload' <ProfileScreen>: name: 'profile' MDToolbar: id: toolbar pos_hint: {"top": 1} elevation: 10 title: "资料页" left_action_items: [["menu", lambda x: nav_drawer.set_state("open")]] MDLabel: text: 'Profile' halign: 'center' MDRectangleFlatButton: text: 'Back' pos_hint: {'center_x':0.5,'center_y':0.1} on_press: root.manager.current = 'menu' <UploadScreen>: name: 'upload' MDToolbar: id: toolbar pos_hint: {"top": 1} elevation: 10 title: "上传页" left_action_items: [["menu", lambda x: nav_drawer.set_state("open")]] ScreenManager: id: upload_sm Screen: name: "scr 1" MDLabel: text: "Screen 1" halign: "center" Screen: name: "scr 2" MDLabel: text: "Screen 2" halign: "center" <ContentNavigationDrawer>: orientation: "vertical" padding: "8dp" spacing: "8dp" ScrollView: MDList: OneLineListItem: text: "Screen 1" on_press: root.nav_drawer.set_state("close") if root.screen_manager.current == "upload": root.screen_manager.current_screen.ids.upload_sm.current = "scr 1" else: root.screen_manager.current = "upload"; root.screen_manager.current_screen.ids.upload_sm.current = "scr 1" OneLineListItem: text: "Screen 2" on_press: root.nav_drawer.set_state("close") if root.screen_manager.current == "upload": root.screen_manager.current_screen.ids.upload_sm.current = "scr 2" else: root.screen_manager.current = "upload"; root.screen_manager.current_screen.ids.upload_sm.current = "scr 2" """ class MenuScreen(Screen): pass class ProfileScreen(Screen): pass class UploadScreen(Screen): pass class ContentNavigationDrawer(BoxLayout): screen_manager = ObjectProperty() nav_drawer = ObjectProperty() class DemoApp(MDApp): def build(self): return Builder.load_string(screen_helper) DemoApp().run()
内容的提问来源于stack exchange,提问作者سید عبدل علی
相关产品推荐
相关产品推荐

