Kivymd数学方程求解程序报错:AttributeError: 'super'对象无__getattr__属性
解决KivyMD中点击按钮触发AttributeError: 'super' object has no attribute 'getattr'的问题
问题场景
开发基于Kivymd的数学方程求解程序,点击界面中的“Cal”或“Expand”按钮时,触发错误:
AttributeError: 'super' object has no attribute '__getattr__'
程序相关代码:
from kivymd.app import MDApp from kivy.lang import Builder from kivy.core.window import Window from kivymd.uix.screen import MDScreen from kivy.properties import DictProperty from kivymd.uix.screenmanager import MDScreenManager __version__ = "1.0.0" kv = """WindowManager: Home: Heugebra: <Home>: name: "Home" FloatLayout: orientation: "vertical" MDCard: size: 500,400 FloatLayout: size: 500,400 MDTextField: id: Equ hint_text: "Insert the Equation" size_hint: None,None width: 200 pos_hint: {"x": 0.3,"y": 0.3} on_text_validate: root.get_data() MDLabel: id: Eq_anser text: "test" pos_hint: {"x": 0.4,"y": 0.3} MDRoundFlatButton: text: "Cal" pos_hint: {"x": 0.8,"y": 0.3} on_press: app.get_data() MDRoundFlatButton: text: "Expand" pos_hint: {"X": 0.4, "y": 0.3} on_press: app.expand() MDRoundFlatButton: text: "Draw" pos_hint: {"x": 0.4,"y": 0.25} on_release: app.root.current = "Heugebra" root.manager.transition.direction = "left" MDFloatingActionButtonSpeedDial: data: app.data root_button_anim: True <Heugebra>: name: "Heugebra" MDRoundFlatButton: text: "Back to Home" pos_hint: {"x": 0.3, "Y": 0.5} on_release: app.root.current = "Home" root.manager.transition.direction = "right" """ class WindowManager(MDScreenManager): pass class Home(MDScreen): pass class Heugebra(MDScreen): pass class MAIN(MDApp): data = DictProperty() def on_start(self): Window.set_title('Every Solver') def build(self): self.theme_cls.theme_style = "Dark" self.theme_cls.primary_palette = "Indigo" self.data = { "Integrate": ["math-integral", "on_press", lambda x: self.calculas('int')], "Diff": ["math-diff.png", "on_press", lambda x: self.calculas('diff')], } return Builder.load_string(kv) def calculas(self, calc: str): print(calc) def get_data(self): x = self.root.ids.Equ.text self.root.ids.Eq_anser.text = "None" def expand(self): x = self.root.ids.Equ.text self.root.ids.Eq_anser.text = "None" if __name__ == '__main__': MAIN().run()
错误原因
错误根源在于MAIN类的get_data和expand方法中,self.root指向的是WindowManager(屏幕管理器),而该组件并没有直接包含Equ和Eq_anser这两个控件的ids——这两个控件属于Home屏幕内部的元素,直接通过self.root.ids访问会找不到目标控件,从而触发__getattr__相关的属性错误。
另外,原代码中“Expand”按钮的pos_hint使用了大写的"X",这不符合Kivy的属性命名规范(应为小写"x"),会导致布局异常,建议一并修正。
解决方法
方法一:在App类中获取目标屏幕实例后访问控件
修改MAIN类的get_data和expand方法,先通过屏幕管理器获取Home屏幕的实例,再通过实例访问内部ids:
def get_data(self): # 获取Home屏幕实例 home_screen = self.root.get_screen("Home") x = home_screen.ids.Equ.text home_screen.ids.Eq_anser.text = "None" def expand(self): home_screen = self.root.get_screen("Home") x = home_screen.ids.Equ.text home_screen.ids.Eq_anser.text = "None"
同时修正kv中Expand按钮的pos_hint:
MDRoundFlatButton: text: "Expand" pos_hint: {"x": 0.4, "y": 0.3} # 将大写X改为小写x on_press: app.expand()
方法二:将逻辑迁移到Home屏幕类中(更符合Kivy的MVC设计)
将数据获取和处理的逻辑放在Home屏幕类内部,直接通过self.ids访问控件,同时调整按钮的绑定事件:
- 修改kv文件中的按钮绑定:
MDRoundFlatButton: text: "Cal" pos_hint: {"x": 0.8,"y": 0.3} on_press: root.get_data() # 改为调用根布局(Home屏幕)的方法 MDRoundFlatButton: text: "Expand" pos_hint: {"x": 0.4, "y": 0.3} # 修正大写X为小写x on_press: root.expand()
- 更新
Home类,添加对应的方法:
class Home(MDScreen): def get_data(self): x = self.ids.Equ.text self.ids.Eq_anser.text = "None" def expand(self): x = self.ids.Equ.text self.ids.Eq_anser.text = "None"
- 删除
MAIN类中的get_data和expand方法。
两种方法都能解决错误,方法二更贴合Kivy的组件设计思路,推荐使用。
内容的提问来源于stack exchange,提问作者Hashem Alsharif
相关产品推荐
相关产品推荐

