QTreeView 禁用某些行的选择

问题描述 投票:0回答:3

我有一个

JSON
模型,我用
QTreeView
:

填充它
*-group1
| |  
| *-item1     value1
| |
| *-item2     value2
|
*-group2
  |
  *-item4     value3

现在我想禁用

groups
的选择,以便用户只能选择带有
items
的行。我想在不修改模型的情况下实现它。

c++ qt qt5
3个回答
3
投票

使用代理模型,例如 QIdentityProxyModel 并重新实现 QAbstractItemModel::flags(),删除组项的 Qt::ItemIsSelectable 标志:

Qt::ItemFlags DisableGroupProxyModel::flags(const QModelIndex& index) const {
   const auto flags = QIdentityProxyModel::flags(index);
   if (index is group) {
       return flags & ~Qt::ItemIsSelectable;
   }

   return flags;
}

然后将原始(未修改的)模型设置为该代理模型的源模型,并将代理模型实例设置为树视图的模型:

DisableGroupProxyModel* proxy = new DisableGroupProxyModel(this);
proxy->setSourceModel(originalModel);
treeView->setModel(proxy);

1
投票

这可以通过

QItemSelectionModel
来完成。您可以通过

获取选择模型
treeView->selectionModel();

然后连接模型信号

void currentRowChanged(const QModelIndex &current, const QModelIndex &previous)

并在连接的插槽内检查新索引是否为组,如果组只需选择

previous
模型索引。


0
投票

我想要一个使用开箱即用的 QTreeWidget 的简单解决方案,我对 @Evgeny 的解决方案没有太多运气,但我在

itemSelectionChanged
信号方面取得了更大的成功。下面是我最终所做的一个最小的工作示例 - 抱歉它不是用 C++ 编写的,我是 PySide Pleb :)

class MyWidget(QWidget):

    def setup_tree(self):

        # a basic tree widget, no further jiggery pokery required.
        self.tree = QTreeWidget()

        # allows multiple selection with ctrl+click, shift+click etc.
        self.tree.setSelectionMode(QTreeWidget.ExtendedSelection)  

        # this is where the magic happens
        self.tree.itemSelectionChanged.connect(self.on_item_selection_changed)

        # add the tree to layouts etc. as normal

    def on_item_selection_changed(self)

        selected = self.tree.selectedItems()

        # filter out nodes we consider un-selectable, in my case anything with data 
        # on the user role, but this could be changed to any criteria
        valid = filter(lambda item: item.data(0, Qt.UserRole, selected)

        # block signals while updating selection 
        # so we don't trigger itemSelectionChanged again before we're done
        self.tree.blockSignals(True)

        for item in valid:
            item.setSelected(True)

        self.tree.blockSignals(False)

© www.soinside.com 2019 - 2024. All rights reserved.