Kivy开发求助:使用ScreenManager切换屏幕时遇AttributeError错误
嘿,这个错误我太熟了!当初刚用Kivy搞ScreenManager的时候也踩过一模一样的坑,给你掰扯清楚为啥会这样以及怎么搞定~
错误成因分析
这个AttributeError: 'super' object has no attribute '__getattr__'在ScreenManager场景下,大多是因为你访问屏幕/组件的方式不对,常见的几个触发点:
- 访问了未定义的屏幕标识:比如你在KV文件里没给Screen设置
name属性,或者Python代码里用了错误的id/名字去调用屏幕 - 混淆了ScreenManager的引用逻辑:比如乱用
super()去访问屏幕,或者没拿到正确的ScreenManager实例就调用切换方法 - KV与Python代码不匹配:比如KV里的ScreenManager名字和Python里的变量名不一致,导致代码找不到对应的屏幕对象
修复方法
针对上面的原因,给你几个具体的解决步骤:
1. 确保每个Screen都有正确的name属性
不管是在Python代码里创建Screen,还是在KV文件里定义,都必须给每个Screen指定name,这是ScreenManager识别屏幕的关键:
- Python代码里创建:
from kivy.uix.screenmanager import Screen login_screen = Screen(name='login') # 明确指定name - KV文件里定义:
Screen: name: 'main' # 给屏幕命名
2. 用正确的方式切换屏幕
切换屏幕时,要通过正确的ScreenManager实例来操作:
- 如果是在某个Screen的内部方法里,直接用
self.manager获取当前的ScreenManager,然后设置current属性:def switch_to_main(self): self.manager.current = 'main' # 这里的'main'是目标屏幕的name - 如果是在App类里,通过
self.root获取ScreenManager(前提是你把ScreenManager作为App的root返回):
❌ 别乱用class MyApp(App): def build(self): return ScreenManager() # 返回ScreenManager作为根组件 def some_method(self): self.root.current = 'login' # 通过root访问ScreenManagersuper()去访问屏幕,这是很多新手容易犯的错!
3. 核对KV与Python代码的对应关系
如果你用KV语言来定义界面结构,一定要确保:
- KV里的ScreenManager和Python里的实例是对应的(比如Python里创建的ScreenManager是App的root,KV里的根组件就是这个ScreenManager)
- 不要用错误的id去访问屏幕,比如你在KV里没给Screen设id,就别在Python里用
self.ids.login_screen去调用
简单示例参考
给你一个能正常运行的极简示例,对比下你的代码哪里出问题:
Python代码:
from kivy.app import App from kivy.uix.screenmanager import ScreenManager, Screen class LoginScreen(Screen): def go_to_main(self): # 正确的切换方式 self.manager.current = 'main' class MainScreen(Screen): def go_back(self): self.manager.current = 'login' class MyKivyApp(App): def build(self): sm = ScreenManager() sm.add_widget(LoginScreen(name='login')) sm.add_widget(MainScreen(name='main')) return sm if __name__ == '__main__': MyKivyApp().run()
对应的KV文件(命名为mykivyapp.kv,和App类名对应):
<LoginScreen>: Button: text: '进入主界面' on_press: root.go_to_main() <MainScreen>: Button: text: '返回登录界面' on_press: root.go_back()
如果你的代码里还有其他细节问题,比如在初始化阶段就去访问未加载的组件,也可能触发类似错误,记得确保所有屏幕都被添加到ScreenManager之后再进行切换操作哦~
内容的提问来源于stack exchange,提问作者Omar Amer
相关产品推荐
相关产品推荐

