c++qtqabstractitemviewqitemselectionmodel

Locking selection in QTableView/QTreeView


Is it possible to "lock" selection in QAbstractView?

I have a form with:

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:

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.


Solution

  • After a long time and no answer from the community, the best solution I can come up with is:

    1. Subclassing QItemSelectionModel to:
      • Create a private attribute bool selectionLocked; that drives when changes of selection must be disallowed.
      • Override all the virtual public slots so that, when selectionLocked == true, they immediately return.
    2. Using a QIdentityProxyModel as was explained in that answer (in the section discussing QTBUG-49966) to cope with selection models being created every time setModel(...) 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 of QAbstractItemView::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.