我有一个
JSON
模型,我用 QTreeView
: 填充它
*-group1
| |
| *-item1 value1
| |
| *-item2 value2
|
*-group2
|
*-item4 value3
现在我想禁用
groups
的选择,以便用户只能选择带有 items
的行。我想在不修改模型的情况下实现它。
使用代理模型,例如 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);
这可以通过
QItemSelectionModel
来完成。您可以通过获取选择模型
treeView->selectionModel();
然后连接模型信号
void currentRowChanged(const QModelIndex ¤t, const QModelIndex &previous)
并在连接的插槽内检查新索引是否为组,如果组只需选择
previous
模型索引。
我想要一个使用开箱即用的 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)