tsragravorogh
tsragravorogh

Reputation: 3173

QTreeWidgetItem setting not selectable clears the selection

I have a QTreeWidget and I want certain rows to be non select-able, which can be achieved by QTreeWidgetItem::setFlags(treeWidgetItem->flags() & ~Qt::ItemIsSelectable).

The problem is that I have an existing row that is already selected and later I click on the non select-able row, selectedItems() returns an empty list. I want the selected row to keep its selection if the user tries to select a non select-able row.

Should I keep track of the selection and handle this scenario in the code, or this can be achieved somehow else. I'd rather not reinvent the wheel.

Thank you.

Upvotes: 3

Views: 2706

Answers (1)

scopchanov
scopchanov

Reputation: 8429

Cause

Calling QTreeView::mousePressEvent(event) clears the selection when clicked on a non-selectable item if the selection mode is set to QAbstractItemView::SingleSelection.

Solution

My solution would be to either:

or (in case this is not desired):

  • Reimplement the mouse events in a subclass of QTreeWidget in order to bypass the default behavior.

Note: In either case, use the QItemSelectionModel::selectionChanged signal to get the list of the selected items.

Example

Here is an example re-implementation of the mouse events in MyTreeWidget preventing the selection of being cleared by clicking a non-selectable item. The top item is expanded/collapsed on a double click:

void MyTreeWidget::mousePressEvent(QMouseEvent *event)
{
    if (indexAt(event->pos())->flags() & Qt::ItemIsSelectable)
        QTreeWidget::mousePressEvent(event);
}

void MyTreeWidget::mouseDoubleClickEvent(QMouseEvent *event)
{
    QTreeWidget::mouseDoubleClickEvent(event);

    QTreeWidgetItem *item = itemAt(event->pos());

    if (item && item->childCount())
        item->setExpanded(!item->isExpanded());
}

The modified in the described manner version of the provided example is available on GitHub.

Improvements

Special thanks to @eyllanesc for making this example more waterproof by:

  • adding a check if item is not NULL
  • replacing itemAt with indexAt

Upvotes: 2

Related Questions