如何在KivyMD的ScreenManager多页面中复用MDToolbar减少重复代码
解决方法
核心是调整布局层级,将通用的头部、侧边栏组件提取到全局,仅用ScreenManager管理各页面独有的内容部分,彻底消除重复代码。
1. 调整后的Python代码
你原来冗余的全局ScreenManager实例可以直接删除,KV中会自动完成页面注册:
from kivymd.app import MDApp from kivymd.uix.screen import Screen from kivy.lang import Builder # 你的KV字符串存入navigation_helper变量即可 navigation_helper = """ # 此处填入下方调整后的KV代码 """ class HomeScreen(Screen): pass class ProfilScreen(Screen): pass class ContactScreen(Screen): pass class DemoApp(MDApp): def build(self): self.theme_cls.primary_palette = 'Red' screen = Builder.load_string(navigation_helper) # 全局保存toolbar引用,方便后续修改标题等属性 self.toolbar = screen.ids.toolbar return screen def nav_drawer(self): pass DemoApp().run()
2. 调整后的KV代码
重新梳理结构,将通用组件全部提取到最外层:
MDNavigationLayout: # 主内容区 BoxLayout: orientation: 'vertical' # 全局共用的MDToolbar,仅定义一次 MDToolbar: id: toolbar title: 'Demo Application' left_action_items: [["menu", lambda x: nav_drawer.set_state('toggle')]] elevation: 10 # 仅用来切换页面内容的ScreenManager ScreenManager: id: screen_manager HomeScreen: ProfilScreen: ContactScreen: # 全局共用的侧边栏,仅定义一次 MDNavigationDrawer: id: nav_drawer BoxLayout: orientation: 'vertical' spacing: '8dp' padding: '8dp' Image: source: 'img\logo.png' size_hint: .5, .5 pos_hint: {"center_x": 0.5} MDLabel: text: 'Le Réseau Foncier' font_style: 'Subtitle1' size_hint_y: None height: self.texture_size[1] MDLabel: text: 'contact@lereseaufoncier.fr' font_style: 'Caption' size_hint_y: None height: self.texture_size[1] ScrollView: MDList: OneLineIconListItem: text: 'Home' on_press: screen_manager.current= 'home' nav_drawer.set_state('close') IconLeftWidget: icon: 'home' on_press: screen_manager.current= 'home' nav_drawer.set_state('close') OneLineIconListItem: text: 'Profile' on_press: screen_manager.current= 'profil' nav_drawer.set_state('close') IconLeftWidget: icon: 'android' on_press: screen_manager.current= 'profil' nav_drawer.set_state('close') OneLineIconListItem: text: 'Contact' on_press: screen_manager.current= 'contact' nav_drawer.set_state('close') IconLeftWidget: icon: 'phone' on_press: screen_manager.current= 'contact' nav_drawer.set_state('close') # 各页面仅保留独有内容,无需再定义Toolbar和侧边栏 <HomeScreen>: name: 'home' BoxLayout: orientation: 'vertical' padding: 35 MDLabel: text: "首页内容" <ProfilScreen>: name: 'profil' BoxLayout: orientation: 'vertical' padding: 35 MDLabel: text: "个人资料内容" <ContactScreen>: name: 'contact' BoxLayout: orientation: 'vertical' padding: 35 MDLabel: text: "联系页内容"
拓展说明
如果需要不同页面显示不同的Toolbar标题,只需要在对应页面类中添加on_enter回调即可,示例:
class HomeScreen(Screen): def on_enter(self, *args): # 直接调用App中保存的toolbar引用修改标题 MDApp.get_running_app().toolbar.title = "首页" class ProfilScreen(Screen): def on_enter(self, *args): MDApp.get_running_app().toolbar.title = "个人资料"
内容的提问来源于stack exchange,提问作者Romain Plantureux
相关产品推荐
相关产品推荐

