I subclassed a QTreeWidget, set its dragDropMode to InternalMove and populated it with custom items, some of which can be dragged, others accept drops. The user can move items around the tree as expected. But I need to be notified of the change in the order of items and react appropriately. Unfortunately, there are no signals associated with the movement of items inside the tree that I could connect to.
I tried getting a handle to the QTreeWidget's underlying model(), then connecting to its rowsMoved signal, but it doesn't seem to be emitted during internal moves.
I reimplemented QTreeWidget's dropEvent(), but there's no way to determine the destination row index there.
The dropMimeData() event doesn't get called at all for internal moves, apparently.
Any other approach I could try? Thanks.
In the reimplemented dropEvent()
, you should be able to find the destination row index and item:
void
subclass::dropEvent(QDropEvent* event)
{
QModelIndex index = indexAt(event->pos());
if (!index.isValid()) { // just in case
event->setDropAction(Qt::IgnoreAction);
return;
}
QTreeWidgetItem* destination_item = itemFromIndex(index);
....
}
The OP actually asked how to get notified about an internal move, that is how to do it without sub-classing QTreeWidget (at least that's how I use internal move since it's built-in functionality). I just found a way it can be done: connect to the QTreeWidget model's rowsInserted() signal!
connect(treeWidget->model(), SIGNAL(rowsInserted(const QModelIndex &, int, int)), this, SLOT(rowsInserted(const QModelIndex &, int, int)));
Incidentally, I figured out an another way to find out which element moved exactly where, which sidesteps the whole dropIndicatorPosition() and the associated itemAbove(), itemBelow() mess, or may at least help somewhat in supplementing it when moving items between different parents:
void MyTreeWidget::dropEvent(QDropEvent *event)
{
// get the list of the items that are about to be dragged
QList<QTreeWidgetItem*> dragItems = selectedItems();
// find out their row numbers before the drag
QList<int> fromRows;
QTreeWidgetItem *item;
foreach(item, dragItems) fromRows.append(indexFromItem(item).row());
// the default implementation takes care of the actual move inside the tree
QTreeWidget::dropEvent(event);
// query the indices of the dragged items again
QList<int> toRows;
foreach(item, dragItems) toRows.append(indexFromItem(item).row());
// notify subscribers in some useful way
emit itemsMoved(fromRows, toRows);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With