import pandas as pd
from PySide6.QtCore import QAbstractTableModel, QModelIndex, Qt
from PySide6.QtWidgets import QDialog, QTableView, QVBoxLayout
[docs]
class PandasModel(QAbstractTableModel):
"""A model to interface a Qt view with pandas dataframe"""
def __init__(self, dataframe: pd.DataFrame, parent=None):
QAbstractTableModel.__init__(self, parent)
self._dataframe = dataframe
[docs]
def rowCount(self, parent=QModelIndex()) -> int:
"""Override method from QAbstractTableModel
Return row count of the pandas DataFrame
"""
if parent == QModelIndex():
return len(self._dataframe)
return 0
[docs]
def columnCount(self, parent=QModelIndex()) -> int:
"""Override method from QAbstractTableModel
Return column count of the pandas DataFrame
"""
if parent == QModelIndex():
return len(self._dataframe.columns)
return 0
[docs]
def data(self, index: QModelIndex, role=Qt.ItemDataRole):
"""Override method from QAbstractTableModel
Return data cell from the pandas DataFrame
"""
if not index.isValid():
return None
if role == Qt.DisplayRole:
return str(self._dataframe.iloc[index.row(), index.column()])
return None
[docs]
def headerData(
self, section: int, orientation: Qt.Orientation, role: Qt.ItemDataRole
):
"""Override method from QAbstractTableModel
Return dataframe index as vertical header data and columns as horizontal header data.
"""
if role == Qt.DisplayRole:
if orientation == Qt.Horizontal:
return str(self._dataframe.columns[section])
if orientation == Qt.Vertical:
return str(self._dataframe.index[section])
return None
[docs]
class DataTableDialog(QDialog):
def __init__(self, df, parent=None):
super().__init__(parent)
view = QTableView(parent=parent)
view.resize(800, 500)
view.horizontalHeader().setStretchLastSection(True)
view.setAlternatingRowColors(True)
view.setSelectionBehavior(QTableView.SelectRows)
model = PandasModel(df)
view.setModel(model)
self.setWindowTitle(self.parent().windowTitle())
layout = QVBoxLayout()
layout.addWidget(view)
self.setLayout(layout)