import pandas as pd from PyQt6 import QtCore from PyQt6.QtCore import Qt def _get_str_dataframe(df: pd.DataFrame) -> pd.DataFrame: """Return a given dataframe with all values turned into strings. When the data given to the PandasModel class contains non-strings, an attached QTableView seems to respond rather slowly. This function turns all data in the DataFrame into strings, yielding a better experience. """ return df.astype(str) class PandasModel(QtCore.QAbstractTableModel): def __init__(self, parent=None): QtCore.QAbstractTableModel.__init__(self, parent) self._data = pd.DataFrame() self._data_str = pd.DataFrame() self._horizontalHeaders = None # Overloaded functions def rowCount(self, parent=None): return len(self._data_str.values) def columnCount(self, parent=None): return self._data_str.columns.size def data(self, index, role=Qt.ItemDataRole.DisplayRole): if not index.isValid(): return QtCore.QVariant() if role != Qt.ItemDataRole.DisplayRole: return QtCore.QVariant() item = self._data_str.iloc[index.row(), index.column()] return QtCore.QVariant(str(item)) def headerData(self, section, orientation, role=Qt.ItemDataRole.DisplayRole): if not ((orientation == Qt.Orientation.Horizontal) and (role == Qt.ItemDataRole.DisplayRole)): return super().headerData(section, orientation, role) return self._horizontalHeaders[section] # Other functions def set_dataframe(self, df): self._data = df self._data_str = _get_str_dataframe(df) self._horizontalHeaders = list(df.columns) self.layoutAboutToBeChanged.emit() self.layoutChanged.emit() def get_dataframe(self) -> pd.DataFrame: return self._data