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);
}