Home > Blockchain >  Format selected columns in QAbstractTableModel from large pandas dataframes
Format selected columns in QAbstractTableModel from large pandas dataframes

Time:10-30

The code below produces a QTableView that is generated from a Pandas DataFrame. columns A and B contain int values, C contains a list of ints for each cell.

This currently is displayed as int values. My question is, how do I make columns B and C display as hex values but keep column A as int's. I do not want to change anything under the if __main__.

from PyQt5 import QtCore, QtWidgets
import numpy as np
import sys
import pandas as pd


class raw_data_table_view(QtWidgets.QTableView):
    def __init__(self, data):
        QtWidgets.QTableView.__init__(self)
        self.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection)
        self.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents)
        model = PandasModel(data)
        self.setModel(model)


class PandasModel(QtCore.QAbstractTableModel):
    def __init__(self, data, parent=None):
        QtCore.QAbstractTableModel.__init__(self, parent)
        self._data = np.array(data.values)
        self._cols = data.columns
        self.r, self.c = np.shape(self._data)

    def rowCount(self, parent=None):
        return self.r

    def columnCount(self, parent=None):
        return self.c

    def data(self, index, role=QtCore.Qt.DisplayRole):
        if index.isValid():
            if role == QtCore.Qt.DisplayRole:
                return str(self._data[index.row(), index.column()])
        return None

    def headerData(self, p_int, orientation, role):
        if role == QtCore.Qt.DisplayRole:
            if orientation == QtCore.Qt.Horizontal:
                return self._cols[p_int]
            elif orientation == QtCore.Qt.Vertical:
                return p_int
        return None


if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    length = 300000
    df = pd.DataFrame(np.random.randint(0, 100, size=(length, 2)),
                      columns=list('AB'))
    df['C'] = list(np.random.randint(0, 255, size=(length, 8)))

    window = raw_data_table_view(df)
    window.resize(400, 800)
    window.show()

    sys.exit(app.exec_())

CodePudding user response:

You can select the relevant column via the index argument, and then format the column value as appropriate when returning the data:

def data(self, index, role=QtCore.Qt.DisplayRole):
    if index.isValid():
        if role == QtCore.Qt.DisplayRole:
            column = index.column()
            data = self._data[index.row(), index.column()]
            if column == 1:
                return hex(data)
            elif column == 2:
                with np.printoptions(formatter={'int':hex}):
                    return str(data)
            else:
                return data
    return None

Result:

screenshot

  • Related