'What is the correct way to update data/rows in a QAbstractTableModel backed by a DataFrame?
I have the following class derived from QAbstractTableModel
import pandas as pd
from typing import List, Any
from PyQt5 import QtCore, QtWidgets
class DataModel(QtCore.QAbstractTableModel):
data_updated = QtCore.pyqtSignal()
def __init__(self, data: pd.DataFrame = pd.DataFrame()):
super(DataModel, self).__init__()
self._data = data
def update_data(self, data: pd.DataFrame):
self.beginInsertRows(QtCore.QModelIndex(), 0, self.rowCount())
self._data = data
self.endInsertRows()
self.data_updated.emit()
def data(self, index, role):
if role == QtCore.Qt.DisplayRole:
return str(self._data.iloc[index.row()][index.column()])
def rowCount(self, index = None) -> int:
return self._data.shape[0]
def columnCount(self, index = None) -> int:
return self._data.shape[1]
def headerData(self, section: int, orientation: QtCore.Qt.Orientation, role: int ) -> Any:
# section is the index of the column/row.
if role == QtCore.Qt.DisplayRole:
if orientation == QtCore.Qt.Horizontal:
return str(self._data.columns[section])
if orientation == QtCore.Qt.Vertical:
return str(self._data.index[section])
The issue I have is that when I update the data in the DataModel using update_data, I'm passing in a full dataframe and replacing the existing dataframe. This is probably not the right way to do it since I see examples online of modifying rows one by one. The current method seems to cause a segfault over time e.g. after multiple data updates. I also occasionally get these types of errors:
QAbstractItemModel::endInsertRows: Invalid index ( 36 , 0 ) in model QSortFilterProxyModel(0x55b4e0d007f0)
This model is used in the following way:
class DataView(QtWidgets.QWidget):
def __init__(self):
super(DataView, self).__init__()
self.model = DataModel()
self.view = QtWidgets.QTableView(self)
self.view.setAlternatingRowColors(True)
self.view.setStyleSheet('alternate-background-color: grey;background-color: white;')
self.proxy = QtCore.QSortFilterProxyModel(self)
self.proxy.setSourceModel(self.model)
self.view.setModel(self.proxy)
Is the right way to do this to diff the old dataframe and the new dataframe and individually update those rows in DataModel? Is there a better way of doing this? I would prefer to keep the dataframe as the backing datastructure if possible.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
