Kivy中通过KV按钮为MDDatatable添加行失败,无法访问数据表
解决Kivy中无法通过Start按钮向MDDatatable添加行的问题
问题根源
报错AttributeError: type object 'MainScreen' has no attribute 'data_tabels'的核心原因:
data_tabels是MainScreen实例对象的属性,不是类本身的属性,你却试图通过类名MainScreen访问它- 调用
add_data方法时,错误地传入类本身而非类的实例
修正后的代码
Python文件
from kivy.config import Config Config.set('graphics','width','1280') Config.set('graphics','height','800') Config.set('graphics', 'resizable', False) Config.write() from kivymd.app import MDApp from kivy.core.window import Window from kivymd.uix.datatables import MDDataTable from kivy.metrics import dp from kivymd.uix.screen import MDScreen class MainScreen(MDScreen): def load_table(self): data_tables = MDDataTable( pos_hint={'center_x': 0.81,'center_y': 0.3}, size_hint=(None, None), size = (460, 460), use_pagination=True, column_data=[("No.", dp(10)), ("UID", dp(30)), ("Reichweite in cm", dp(30))], row_data=[ ("1", "x100", "30")]) self.add_widget(data_tables) return data_tables def on_enter(self): # 这里是实例属性,存储当前屏幕的数据表对象 self.data_tabels = self.load_table() def add_data(self): # 使用self访问当前实例的data_tabels属性 self.data_tabels.add_row(("1","2","3")) class SettingsScreen(MDScreen): pass class MyMDApp(MDApp): # 重命名类名,避免和导入的MDApp冲突 def __init__(self, **kwargs): super().__init__(**kwargs) self.load_kv("mdapp.kv") def clkfunc(self): Window.close() self.stop() def Start(self): print("Achse bewegt sich") print("Reader Liest") # 获取MainScreen的实例对象,而非类本身 main_screen = self.root.get_screen("main_screen") main_screen.add_data() def Stop(self): print("Messung wird abgebrochen") if __name__ == '__main__': MyMDApp().run()
KV文件
#:kivy 1.0.9 #: import NoTransition kivy.uix.screenmanager.NoTransition <MainScreen>: MDScreen: canvas: Color: rgba: 0,0,1,1 Rectangle: pos: 0,0 size: 800, 800 FloatLayout: Button: text: 'Quit' on_press: app.clkfunc() pos: 1210, 780 size_hint: None, None size: 70, 20 Button: text: 'Start' # 更直接的方式:直接调用当前屏幕的add_data方法,无需经过app on_press: root.add_data() pos: 1050, 650 size_hint: None, None size: 200, 80 Button: text: 'Stopp' on_press: app.Stop() pos: 1050, 550 size_hint: None, None size: 200, 80 <SettingsScreen>: BoxLayout: Button: text: 'My settings button' Button: text: 'Back to Main' on_press: root.manager.current = 'main' ScreenManager: id: screen_manager transition: NoTransition() MainScreen: id: main_screen name: "main_screen"
关键修改点解释
区分类和实例:
self.data_tabels是MainScreen实例的属性,只能通过实例对象访问,不能用类名MainScreen访问- 在
MyMDApp的Start方法中,通过self.root.get_screen("main_screen")获取到实际运行的MainScreen实例,再调用它的add_data方法
优化方法调用(可选):
- KV文件中可以直接用
root.add_data()调用当前屏幕的方法,跳过app的中间层,更符合Kivy的MVC架构逻辑
- KV文件中可以直接用
类名冲突修复:
- 原代码中自定义的App类名也是
MDApp,和导入的MDApp重名,修改为MyMDApp避免命名冲突
- 原代码中自定义的App类名也是
简化停止逻辑:
clkfunc方法中直接用self.stop()即可,无需调用MDApp.get_running_app().stop()
内容的提问来源于stack exchange,提问作者Sebastian Hösing
相关产品推荐
相关产品推荐

