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

KivyMD导航抽屉无法切换屏幕问题求助

问题分析与解决

你的代码存在三个核心问题导致屏幕无法切换:

  1. 重复实例化Screen且结构错误
    KV语言中,你在ScreenManager内部已经声明了Screen1/Screen2/Screen3,但又在外部重复定义了这三个Screen。外部的Screen不属于ScreenManager管理,自然无法被切换显示。

  2. 操作了错误的ScreenManager实例
    你全局创建了sm对象并添加Screen,但界面实际使用的是KV中定义的screen_manager实例,change_screen方法修改的是全局sm的current属性,和界面显示的ScreenManager无关。

  3. 导航抽屉的引用问题
    KV中MDTopAppBar的left_action_items里引用nav_drawer时,需要确保上下文能正确找到这个ID,原结构中nav_drawer和ScreenManager同级,需要通过根布局访问。


修正后的完整代码
from kivymd.app import MDApp
from kivy.lang.builder import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.core.window import Window

Window.size = (360, 750)

helpstring = """
<MyApp>:
    theme_cls: theme_cls
    screen_manager: screen_manager

Screen:
    BoxLayout:
        orientation: 'horizontal'
        
        MDNavigationDrawer:
            id: nav_drawer
            orientation: 'vertical'
            elevation: 2
            MDScrollView:   
                MDList:
                    OneLineIconListItem:
                        text: "Screen 1"
                        on_press: app.change_screen('screen1')
                        IconLeftWidget:
                            icon: 'human-male'
                    OneLineIconListItem:
                        text: "Screen 2"
                        on_press: app.change_screen('screen2')
                        IconLeftWidget:
                            icon: 'dog'

                    OneLineIconListItem:
                        text: "Screen 3"
                        on_press: app.change_screen('screen3')
                        IconLeftWidget:
                            icon: 'cat'  

        ScreenManager:
            id: screen_manager
            Screen1:
            Screen2:
            Screen3:

<Screen1>:
    name: 'screen1'
    MDBoxLayout:
        orientation: 'vertical'
        
        MDTopAppBar:
            type: 'top'
            title: 'Screen 1'
            left_action_items: [['menu', lambda x: root.parent.parent.ids.nav_drawer.set_state()]]
        Widget:

<Screen2>:
    name: 'screen2'
    MDBoxLayout:
        orientation: 'vertical'
        
        MDTopAppBar:
            type: 'top'
            title: 'Screen 2'
            left_action_items: [['menu', lambda x: root.parent.parent.ids.nav_drawer.set_state()]]
        Widget:

<Screen3>:
    name: 'screen3'
    MDBoxLayout:
        orientation: 'vertical'
        
        MDTopAppBar:
            type: 'top'
            title: 'Screen 3'
            left_action_items: [['menu', lambda x: root.parent.parent.ids.nav_drawer.set_state()]]
        Widget:
"""


class Screen1(Screen):
    pass


class Screen2(Screen):
    pass


class Screen3(Screen):
    pass


class MyApp(MDApp):
    def build(self):
        return Builder.load_string(helpstring)

    def change_screen(self, name):
        # 访问KV中定义的screen_manager实例
        self.root.ids.screen_manager.current = name


if __name__ == "__main__":
    MyApp().run()

关键修改点说明
  • 调整布局结构:将MDNavigationDrawer和ScreenManager放在同一个水平BoxLayout中,确保导航抽屉和内容区域并列,同时移除了外部重复定义的Screen,所有Screen都归ScreenManager管理。
  • 使用正确的ScreenManager实例:change_screen方法中通过self.root.ids.screen_manager获取界面上实际使用的ScreenManager,而不是全局的sm对象。
  • 修复导航抽屉引用:TopAppBar中通过root.parent.parent.ids.nav_drawer正确找到导航抽屉的ID,确保菜单按钮能正常打开抽屉。
  • 给每个Screen添加TopAppBar:每个页面都添加了独立的TopAppBar,方便在不同页面都能打开导航抽屉。

内容的提问来源于stack exchange,提问作者TS46

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 21:05:20