Make QTableView rows not selectable

During a project I had to make rows within a QTableview not selectable based on a columns value. Searching arround the internet showed me how but.... After implementing the most reasonable solution ( check the column value and return via reimplemented flags() function of my model Qt.NoItemFlags ) I stumbled apon the issue, that selecting enabled rows, was extremly slow.

I had a lot of data within my model, so maybe this was the issue. So don't ask the model.data(index, role) if the row is selectable, ask yourself.

First step: iterate over all rows and store within a dictionary which row has which flag for it's cells. *Better* But... still slow.

Through a litte miss if else I realised using Qt.NoItemFlags  caused this behaviour. But how to fix this? Simple... see code below.

Have Fun

class CashBookRelationModel(QtSql.QSqlRelationalTableModel):

    def __init__(self, parent = None):
        super().__init__(parent)
        self.stored_flags = {}

    def flags(self, index):
        '''check if row should be editable'''
        if not(self.stored_flags):
            #initialize dictionary if not presetnt
            self.update_flags()
        try:
            return self.stored_flags[index.row()]
        except:
            #row not within dict, so update
            self.update_flags(index.row())
            return self.stored_flags[index.row()]

    def update_flags(self, _row = None ):
        '''locally store row state to speed up selecting edit-lines'''
        if _row and not super().data(self.index(_row, self.fieldIndex('collated')), Qt.EditRole):
            #update single row to be editable since new rows are not collated
            self.stored_flags[_row] = Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsEditable
            return
        else:
            #iterate all rows and rebuild stored_flags
            self.stored_flags = {}
            for _r in range(0,self.rowCount()):
                _stat = super().data(self.index(_r, self.fieldIndex('collated')), Qt.EditRole)
                if _stat:
                    self.stored_flags[_r] = Qt.ItemIsSelectable # Don't use Qt.NoItemFlags cause this will slowdown the hell
                else:
                    self.stored_flags[_r] = Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsEditable

The "trick" was not to set Qt.NoItemFlags on line 31. Instead set Qt.ItemIsSelectable.

On the first view this makes absolutly no sence, but since the item is not enabled, it can't be selected ¯\_(ツ)_/¯