Я использую Киви MDDataTables в приложении Python3. Во время выполнения я хочу динамически добавлять и удалять строки в таблице. Когда я добавляю данные с помощью add_row(self, data: Union[list, tuple])
, затем удаляю строки с помощью remove_row(self, data: Union[list, tuple])
, а затем снова начинаю заполнять таблицу, происходит сбой после 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. Вы можете следить за его продвижением там!