I am creating a table inside of a PyQt5 GUI using QTableView. I have 35 rows and 5 columns from a pandas dataframe. Scrolling and sorting the table is extremely slow (on the order of seconds).
I have already looked for solutions, but most people were having trouble with populating the table. One person suggested using a numpy array, but I did not see any increase in performance.
Here is my code:
def create_table(dataframe):
table = QTableView()
tm = TableModel(dataframe)
table.setModel(tm)
table.setSelectionBehavior(QAbstractItemView.SelectRows)
table.resizeColumnsToContents()
table.resizeRowsToContents()
table.setSortingEnabled(True)
return table
class TableModel(QtCore.QAbstractTableModel):
def __init__(self, data, parent=None):
QtCore.QAbstractTableModel.__init__(self, parent)
self._data = data
def rowCount(self, parent=None):
return len(self._data.values)
def columnCount(self, parent=None):
return self._data.columns.size
def data(self, index, role=QtCore.Qt.DisplayRole):
if index.isValid():
if role == QtCore.Qt.DisplayRole:
return str(self._data.values[index.row()][index.column()])
return None
def headerData(self, rowcol, orientation, role):
if orientation == QtCore.Qt.Horizontal and role == QtCore.Qt.DisplayRole:
return self._data.columns[rowcol]
if orientation == QtCore.Qt.Vertical and role == QtCore.Qt.DisplayRole:
return self._data.index[rowcol]
return None
def flags(self, index):
flags = super(self.__class__, self).flags(index)
flags |= QtCore.Qt.ItemIsEditable
flags |= QtCore.Qt.ItemIsSelectable
flags |= QtCore.Qt.ItemIsEnabled
flags |= QtCore.Qt.ItemIsDragEnabled
flags |= QtCore.Qt.ItemIsDropEnabled
return flags
def sort(self, Ncol, order):
"""Sort table by given column number.
"""
try:
self.layoutAboutToBeChanged.emit()
self._data = self._data.sort_values(self._data.columns[Ncol], ascending=not order)
self.layoutChanged.emit()
except Exception as e:
print(e)
table = create_table(dataframe)
There is one question that I found here Slow scrolling with QTableView on other comp where the user has a similar problem, and he/she found out that the "QTableView is refreshing the items at each scroll / appearance of the window, which is obviously the source of the problem." However I don't know if my table has the same issue as that one.
How can I make scrolling and sorting faster for my table? What are the sources of the problem?
The problem is in the rowCount and data methods since you are not using the best functions. In the case of rowCount when using values you are creating a new data that consumes time, in this case use index. And the same in data, you must use iloc():