QTreeWidgetItem 设置不可选清除选择

QTreeWidgetItem setting not selectable clears the selection

我有一个 QTreeWidget,我希望某些行不能 select,这可以通过 QTreeWidgetItem::setFlags(treeWidgetItem->flags() & ~Qt::ItemIsSelectable).

实现

问题是我有一个已经 selected 的现有行,后来我单击了非 select-able 行,selectedItems() returns空列表。如果用户尝试 select 非 select 行,我希望 selected 行保持其 selection。

我应该跟踪 selection 并在代码中处理这种情况,还是可以通过其他方式实现。我宁愿不重新发明轮子。

谢谢。

原因

如果 selection mode 设置为 QAbstractItemView::SingleSelection,则在单击不可选择的项目时调用 QTreeView::mousePressEvent(event) 会清除选择。

解决方案

我的解决方案是:

或(如果不需要):

  • QTreeWidget 的子类中重新实现鼠标事件以绕过默认行为。

注意:在任何一种情况下,使用QItemSelectionModel::selectionChanged信号获取所选项目的列表。

例子

这是在 MyTreeWidget 中重新实现鼠标事件的示例,防止通过单击不可选择的项目来清除选择。双击最上面的项目是expanded/collapsed:

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());
}

所提供示例的以描述方式修改的版本可在 GitHub 上获得。

改进

特别感谢@eyllanesc 通过以下方式使此示例更加防水:

  • 如果 item 不是 NULL
  • ,则添加检查
  • itemAt 替换为 indexAt