Is it possible to "lock" selection in QAbstractView?
I have a form with:
- A list of objects I can edit (QTableView).
Objects are stored in a database, the list shows their ID. - A
New
button, whose effect is to append an empty row I can edit to create a new ID and enable controls in the rest of the form. - An
Edit
button whose effect is to enable the edition of the rest of the form, but leaves the ID non editable. - Everything is driven by a state machine. There are parallel states but for the sake of this question, only transition between a
Viewing
state and anEditing
state is relevant. Clicking either button enters theEditing
state, which means testing if I am in theEditing
state provides no information about whether I clicked onNew
or onEdit
.
I am trying to lock the selection when entering the Editing
state.
I cannot simply disable the view because I need to edit new IDs, I cannot connect a slot to the selectionChanged signal to restore the selection because of side effects (calls to the database + focus going all over the place), and if possible, I wish to avoid having to call QAbstractItemView::setSelectionModel
(it is reset by QAbstractItemView::setModel
, see below) and wish to drive this behavior thanks only to the Viewing
and Editing
states.
I have tried to use, but to no avail:
QAbstractItemModel::flags
(the best I can do is prevent selecting another item but not clearing the selection.)QAbstractItemView::selectionMode
QItemSelectionModel::select
, withQItemSelectionModel::SelectionFlag::NoUpdate
(The description of this enum value made me think it could block the next selection change but that is not the case).- Subclassing
QItemSelectionModel
(@chehrlic's comment below) to override all thevirtual
public slots.
While it does work (a property can be used to stop the selection from changing), it is a pain thatQAbstractItemView::setModel
creates a new model. It does work now but I do not see any easy way to prevent the code from breaking after accumulating code changes over the span of several years.
Did I miss any existing property to achieve this? And if I did not, how can I implement a property to lock the selection but no have any other effect on my view?
At this point, the last item in the above list of things I tried does do the job but it has a downside I am trying to avoid.
This is similar to this question except it was for a now old version of Qt and the answer is not very satisfying anyway.
After a long time and no answer from the community, the best solution I can come up with is:
bool selectionLocked;
that drives when changes of selection must be disallowed.virtual
public slots so that, whenselectionLocked == true
, they immediately return.QIdentityProxyModel
as was explained in that answer (in the section discussing QTBUG-49966) to cope with selection models being created every timesetModel(...)
is called on the view.If for any reason, I need to change the model attached to a view, I can do it calling
QAbstractProxyModel::setSourceModel
instead ofQAbstractItemView::setModel
, thus ensure the selection model never gets inadvertently reset.This is not the full future-proof solution I was envisioning (this does not protect the application against someone adding a call to
setModel
in the future) but it will do for me.