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

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"

关键修改点解释

  1. 区分类和实例:

    • self.data_tabels是MainScreen实例的属性,只能通过实例对象访问,不能用类名MainScreen访问
    • 在MyMDApp的Start方法中,通过self.root.get_screen("main_screen")获取到实际运行的MainScreen实例,再调用它的add_data方法
  2. 优化方法调用(可选):

    • KV文件中可以直接用root.add_data()调用当前屏幕的方法,跳过app的中间层,更符合Kivy的MVC架构逻辑
  3. 类名冲突修复:

    • 原代码中自定义的App类名也是MDApp,和导入的MDApp重名,修改为MyMDApp避免命名冲突
  4. 简化停止逻辑:

    • clkfunc方法中直接用self.stop()即可,无需调用MDApp.get_running_app().stop()

内容的提问来源于stack exchange,提问作者Sebastian Hösing

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 23:45:03