Kivy MDDataTable IndexError: list index out of range when dynamically add and remove rows

Kivy MDDataTable IndexError: list index out of range when dynamically add and remove rows

我在 Python3 应用程序中使用 Kivy MDDataTables。在运行时,我想在 table 中动态添加和删除行。当我使用 add_row(self, data: Union[list, tuple]) 添加数据时,之后使用 remove_row(self, data: Union[list, tuple]) 删除行,然后再次开始填充 table,它在 20 到 50 行后崩溃并显示以下错误消息:

[INFO   ] [Base        ] Leaving application in progress...
 Traceback (most recent call last):
   File "<PATH TO PROGRAM>\test.py", line 93, in <module>
     sm.run()
   File "<PATH TO VIRTUAL ENV>\lib\site-packages\kivy\app.py", line 950, in run
     runTouchApp()
   File "<PATH TO VIRTUAL ENV>\lib\site-packages\kivy\base.py", line 582, in runTouchApp
     EventLoop.mainloop()
   File "<PATH TO VIRTUAL ENV>\lib\site-packages\kivy\base.py", line 347, in mainloop
     self.idle()
   File "<PATH TO VIRTUAL ENV>\lib\site-packages\kivy\base.py", line 387, in idle
     Clock.tick()
   File "<PATH TO VIRTUAL ENV>\lib\site-packages\kivy\clock.py", line 733, in tick
     self.post_idle(ts, self.idle())
   File "<PATH TO VIRTUAL ENV>\lib\site-packages\kivy\clock.py", line 776, in post_idle
     self._process_events()
   File "kivy\_clock.pyx", line 616, in kivy._clock.CyClockBase._process_events
   File "kivy\_clock.pyx", line 649, in kivy._clock.CyClockBase._process_events
   File "kivy\_clock.pyx", line 645, in kivy._clock.CyClockBase._process_events
   File "kivy\_clock.pyx", line 218, in kivy._clock.ClockEvent.tick
   File "<PATH TO VIRTUAL ENV>\lib\site-packages\kivy\uix\recycleview\__init__.py", line 257, in refresh_views
     lm.set_visible_views(indices, data, viewport)
   File "<PATH TO VIRTUAL ENV>\lib\site-packages\kivy\uix\recyclelayout.py", line 253, in set_visible_views
     refresh_view_layout(index, opt, widget, viewport)
   File "<PATH TO VIRTUAL ENV>\lib\site-packages\kivy\uix\recycleview\layout.py", line 148, in refresh_view_layout
     self.apply_selection(index, view, index in self.selected_nodes)
   File "<PATH TO VIRTUAL ENV>\lib\site-packages\kivy\uix\recycleview\layout.py", line 143, in apply_selection
     view.apply_selection(self.recycleview, index, is_selected)
   File "<PATH TO VIRTUAL ENV>\lib\site-packages\kivymd\uix\datatables\datatables.py", line 1804, in apply_selection
     ic = instance_table_data.recycle_data[index].get("icon", None)
 IndexError: list index out of range

我在 Windows 10 和 Raspbian 11 上试过这个,使用:

在旧版本的程序中,我使用 kivymd 0.104.2 并直接向 self._table.row_data 添加和删除数据。在这个版本的程序中,同样的崩溃发生了。

我发现存在索引超出范围错误,但我无法更改它。 我该怎么做才能修复程序并避免崩溃?

示例代码:

from kivymd.app import MDApp
from kivy.uix.screenmanager import ScreenManager
from kivy.uix.screenmanager import Screen
from kivymd.uix.datatables import MDDataTable
from kivy.metrics import dp
import threading
import time


class TestScreen(Screen):
    def __init__(self, **kw):
        super().__init__(**kw)
        self._table = None
        self.createTable()

    def createTable(self):
        self._table = MDDataTable(
            rows_num=99,
            column_data=[("col1", dp(10)),
                         ("col2", dp(50)),
                         ("col3", dp(20)),
                         ("col4", dp(30)),
                         ("col5", dp(15)),
                         ("col6", dp(15)),
                         ("col7", dp(15)),
                         ])
        self.add_widget(self._table)

    def clearTable(self):
        while len(self._table.row_data) > 0:
            self._table.remove_row(self._table.row_data[-1])

    def updateTable(self, data):
        for item in data:
            row = (str(len(self._table.row_data)),
                   item[0],
                   item[1],
                   item[2],
                   item[3],
                   item[4],
                   item[5])
            self._table.add_row(row)

    def addData(self):
        self.updateTable([("1", "1", "1", "1", "1", "1", "1")] * 5)

    def getTableSize(self):
        return len(self._table.row_data)


class TestApp(MDApp):
    def build(self):
        sm = ScreenManager()
        sm.add_widget(TestScreen())
        return sm


class DataProvider(threading.Thread):
    def __init__(self, sm):
        threading.Thread.__init__(self)
        self.sm = sm

    def run(self):
        time.sleep(1)
        sm.root.current_screen.addData()
        time.sleep(1)
        sm.root.current_screen.clearTable()
        while True:
            sm.root.current_screen.addData()
            time.sleep(1)
            print(sm.root.current_screen.getTableSize())


sm = TestApp()
data_p = DataProvider(sm)
data_p.start()
sm.run()

我将错误添加到 kivymd github project 的错误跟踪器中。你可以在那里关注它的进展!