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 ¯\_(ツ)_/¯