Reputation: 1384
I Have a JSON
model, and I populate it with QTreeView
:
*-group1
| |
| *-item1 value1
| |
| *-item2 value2
|
*-group2
|
*-item4 value3
Now I want to disable selection for groups
, so that user can select only rows with items
. And I want to achive it without modification of model.
Upvotes: 6
Views: 3062
Reputation: 649
I wanted a simple solution that used the QTreeWidget out of the box, and I didn't have much luck with @Evgeny 's solution but I had more success with the itemSelectionChanged
signal. Below is a minimum working example of what I ended up doing - apologies it's not in C++, I am a 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 = list(filter(lambda item: item.data(0, Qt.UserRole), selected))
# if there's no invalid selections, then we're done
if len(valid) == len(selected):
return
# block signals while updating selection
# so we don't trigger itemSelectionChanged again before we're done
self.tree.blockSignals(True)
self.tree.clearSelection()
for item in valid:
item.setSelected(True)
self.tree.blockSignals(False)
Upvotes: 0
Reputation: 25155
Use a proxy model such as QIdentityProxyModel and reimplement QAbstractItemModel::flags(), removing the Qt::ItemIsSelectable flag for the group items:
Qt::ItemFlags DisableGroupProxyModel::flags(const QModelIndex& index) const {
const auto flags = QIdentityProxyModel::flags(index);
if (index is group) {
return flags & ~Qt::ItemIsSelectable;
}
return flags;
}
Then set the original (unmodified) model as source model of this proxy model and the proxy model instance as the tree view’s model:
DisableGroupProxyModel* proxy = new DisableGroupProxyModel(this);
proxy->setSourceModel(originalModel);
treeView->setModel(proxy);
Upvotes: 3
Reputation: 4010
This can be done with QItemSelectionModel
. You can get selection model with
treeView->selectionModel();
Then connect to model's signal
void currentRowChanged(const QModelIndex ¤t, const QModelIndex &previous)
and inside the connected slot check if new index is group or not and if group just select previous
model index.
Upvotes: 1