QListWidget: how to prevent unselect all?
-
A QListWidget in SingleSelection mode allows unselecting the last selected item in several ways, such as Ctrl-click (the docs suggest that it should not allow this, but see the comments on QTBUG-49217). How can I prevent this? My item list must always have one item selected.
I first tried overriding mousePressEvent and ignoring it if necessary. This works, but there are other ways to unselect (e.g. it can happen on mouseMoveEvent), and it seems clunky to find and override them all.
I next tried setting a custom QItemSelectionModel that refuses to unselect the currently selected item. That leads to what may be a Qt bug: QListWidget never issues its itemSelectionChanged signal, even if my QItemSelectionModel has no custom behavior at all. (Apparently my call to QListWidget::setSelectionModel somehow causes the connection between QItemSelectionModel::selectionChanged and QListWidget::itemSelectionChanged to break. See my related question.)
Ideally, QListWidget would have optional require-at-least-one-selection behavior built in. I can't be the only one who needs this.
-
@Franz-Amador
Hello,
See my answer for your related question. I suggest overridingvoid QItemSelectionModel::select(const QModelIndex & index, QItemSelectionModel::SelectionFlags command)
for your selection model to discard the unneeded deselections. Additionally, you should want to override
QAbstractItemView::setSelectionModel
for your list widget to restore the appropriate selection model connections before calling the default implementation.Kind regards.
-
@Franz-Amador
another possible solution can be overriding QAbstractItemView::selectionCommand() and return QItemSelectionModel::NoUpdate in case the selection should not change. -
-
@Xicor Properly speaking, I didn't do either. I just overrode mousePressEvent and did not pass the event along to QAbstractItemView::mousePressEvent if I wanted to block the deselect. It did not occur to me to do anything to the event object itself. I'm guessing that was wrong. (I'm new to Qt.)
-
Yes, the point is valid. If you want to stop the propagation of the event, you are supposed to call
QEvent::accept
and do nothing. However any child widgets you may have are receiving the event before their parent, so it may or may not work. -
@raven-worx Thanks. I ended up using this solution, which seems a bit more direct and focused than overriding "select".