I am using a QTreeWidget to display a tree of parent nodes with their leave
nodes. Each parent can have various leaf nodes but leaf nodes should have no
childs. The user should be able to move leaves between parents by dragging them
to the new position. To avoid leaves from being dropped on other leaves, I have
only set ItemIsDragEnabled
on leaves while having ItemIsDropEnabled
on
parent nodes. This works fine if the QTreeWidget is set to "SingleSelection".
However, if the SelectionMode is set to ExtendedSelection
you are able to
select a leave and a parent node together and drop them both on a leaf: http://i.stack.imgur.com/Kil3y.jpg (Screenshot)
Here is the sample code:
QTreeWidget *tree = this->ui->treeWidget;
QTreeWidgetItem *item;
QTreeWidgetItem *child;
tree->setSelectionMode(QAbstractItemView::ExtendedSelection);
tree->setDefaultDropAction(Qt::MoveAction);
tree->setDragEnabled(true);
tree->setAcceptDrops(true);
tree->setDropIndicatorShown(true);
// disable dropping of leaves as top level items
tree->invisibleRootItem()->setFlags( Qt::ItemIsSelectable |
Qt::ItemIsUserCheckable | Qt::ItemIsEnabled );
for (int i = 0; i < 2; i++) {
// create top level item
item = new QTreeWidgetItem();
item->setText(0, "parent");
item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable
| Qt::ItemIsDropEnabled | Qt::ItemIsEnabled );
// add 3 child items
for (int j = 0; j < 3; j++) {
child = new QTreeWidgetItem();
child->setText(0, "child");
child->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable
| Qt::ItemIsDragEnabled | Qt::ItemIsEnabled );
item->addChild(child);
}
// add item to tree
tree->addTopLevelItem(item);
}
I googled quite a lot but could not come up with a solution. How can I keep child and parent nodes on their respective levels while using ExtendedSelection
?
Do I have to subclass QTreeWidget and override insertRows()? Is there any way to intercept drag'n'drop actions on QTreeWidget so I could check if the action is ok? (If there is a way to get this to work with QStandardItemModel/QTreeView I would be happy too)