Kivy点击Log Out跳转login页报No Screen with name "login"异常
问题根因
触发kivy.uix.screenmanager.ScreenManagerException: No Screen with name "login"异常的核心原因是代码中嵌套了两层独立的ScreenManager,登出操作调用的内层ScreenManager没有注册login屏幕:
- KV文件根节点定义了第一层全局ScreenManager,已经正确注册了
name: "login"的Login屏幕,登录时从login跳homepage操作的就是这层管理器,所以能正常执行。 - 但在
<Homepage>的KV规则内部,又在MDNavigationLayout下新建了第二层id为screen_manager的ScreenManager,这层管理器里只添加了首页、新增客户、新增员工等业务功能页,完全没有添加login屏幕。 - 侧边导航栏所有跳转逻辑绑定的都是这层内层ScreenManager,所以跳同属内层的业务页不会报错,跳属于外层的login页时就会触发找不到屏幕的异常。
除此之外代码里还有几个容易引发后续问题的隐患:
- 自定义类和Kivy原生类重名:Python代码中自定义了
class ScreenManager(ScreenManager),会覆盖原生ScreenManager的引用,极易引发不可预知的组件错误。 - 屏幕命名大小写不统一:内层ScreenManager的首页name写为大写开头的
"Homepage",外层的首页name为小写的"homepage",后续跳转很容易出现匹配错误。 - 冗余类定义:Python中声明的AddNewCustomer、AddNewStaff、DrawerList等自定义Screen类,KV中并没有对应调用,全部直接使用原生Screen组件,属于无效代码。
修复方案
临时快速修复(不用大改现有结构)
直接修改Log Out按钮的跳转逻辑,不要调用内层的子ScreenManager,直接调用App根节点的全局ScreenManager执行跳转,把<Nav>下Log Out按钮的on_release代码替换为:
on_release: root.nav_drawer.set_state("close") app.root.transition.direction = "left" app.root.current = "login"
app.root就是加载KV文件时返回的最外层全局ScreenManager实例,里面已经注册了login屏幕,跳转可以正常执行。
规范结构修复(推荐,避免后续出问题)
- 删除Homepage内部嵌套的多余ScreenManager,全局只保留根节点的一个ScreenManager统一管理所有屏幕(登录页、首页、各业务页全部放在这层管理器下)。
- 调整MDNavigationLayout、MDNavigationDrawer的层级,不要把侧边栏组件放在Homepage屏幕内部,将其作为全局布局组件,绑定全局ScreenManager的引用。
- 删除Python代码中重名的自定义ScreenManager类,统一所有屏幕的name命名规则(建议全部用小写,避免大小写混用),清理没有实际使用的冗余自定义类。
内容的提问来源于stack exchange,提问作者Ewan
相关产品推荐
相关产品推荐

