Increase performance in PYQT6 QAbstractTableModel when using Checkboxes

316 Views Asked by At

I'm using PyQT6 for my application. I'm creating my own QAbstractTableModel where each row has some details and last 3 columns are checkboxes representing received, packed, sent. I successfully implemented the solution. The problem is there is a slight delay(0.3s - rough estimate) which is noticable when (un)checking the checkboxes. Propably the problem is in the performance is there better way to do this? All my data returned from database is in numpy arrays so that shouldn't be a problem.

Here is my class for the table.

class TableModel(QAbstractTableModel):
    def __init__(self, data, headers):
        super(TableModel, self).__init__()
        self._data = data
        self._headers = headers

    def data(self, index, role):
        value = self._data[index.row(), index.column()]
        if not index.isValid():
            return QVariant()

        if role == Qt.ItemDataRole.DisplayRole:
            if value == "True" or value == "False":
                return QVariant("")
            return QVariant(str(value))

        # set checkboxes
        elif role == Qt.ItemDataRole.CheckStateRole:
            if value == "True":
                return QVariant(Qt.CheckState.Checked)
            if value == "False":
                return QVariant(Qt.CheckState.Unchecked)

        elif role == Qt.ItemDataRole.BackgroundRole:
            if value == "True":
                return QVariant(QtGui.QColor("green"))
            if value == "False":
                return QVariant(QtGui.QColor("yellow"))
        elif role == Qt.ItemDataRole.TextAlignmentRole:
            return QVariant(Qt.AlignmentFlag.AlignCenter)

    # checking and unchecking checkbox
    def setData(self, index, value, role):
        if role == Qt.ItemDataRole.CheckStateRole:
            if value is not None:
                if value == 0:
                    self._data[index.row(), index.column()] = False
                elif value == 2:
                    self._data[index.row(), index.column()] = True
                queries.set_checkbox(self._data[index.row()], index.column())
                self.dataChanged.emit(index, index)
                return True
        return False

    def headerData(self, section, orientation, role=Qt.ItemDataRole.DisplayRole):
        if orientation == Qt.Orientation.Horizontal and role == Qt.ItemDataRole.DisplayRole:
            return self._headers[section]
        return super().headerData(section, orientation, role)

    def rowCount(self, index):
        if not self._data.size:
            return 0
        return self._data.shape[0]

    def columnCount(self, index):
        if not self._data.size:
            return 0
        return self._data.shape[1]

    def flags(self, index):
        return Qt.ItemFlag.ItemIsSelectable | Qt.ItemFlag.ItemIsEnabled | Qt.ItemFlag.ItemIsUserCheckable

Here is my code for creating the table:

def get_table(self, view, month):
    """get table from db to show in TableView"""
    deliveries = queries.get_deliveries(month)
    headers = queries.get_delivery_headers()
    self.model = TableModel(deliveries, headers)
    proxymodel = QSortFilterProxyModel()
    proxymodel.setSourceModel(self.model)
    view.setModel(proxymodel)
    view.sortByColumn(0, Qt.SortOrder.AscendingOrder)
    for x in range(2, len(headers)):
        view.resizeColumnToContents(x)
    view.show()
0

There are 0 best solutions below