You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 01:18:03