Search code examples
qtdrag-and-dropqtreewidget

QTreeWidget drag and drop for reordering selects wrong item


After having followed the recommendations given here : QTreeWidget reordering child items by dragging, the dragged item is not selected.

So, quite naturally, I tried to get the dragged item and then call setSelected() on it.

The result is that the item before the correct on is selected.

I subclass QTreeWidget to override dropEvent like this -

QTreeWidgetItem *pItem;
QModelIndex dropIndex = indexAt(pEvent->pos());

if(dropIndex.isValid() == false)
{
    pEvent->setDropAction(Qt::IgnoreAction);
    pEvent->accept();
    return;
}

pItem = this->itemAt(pEvent->pos());
QTreeWidget::dropEvent(pEvent);

How can I get the pointer to the correct QTreeWidgetItem which has been dropped ?


Solution

  • Since the dropped item can "fall" above or below of the target item, you need to manage both situations and calculate the correct index of the moved item. For example:

    [..]
    virtual void dropEvent(QDropEvent * event)
    {
        QModelIndex droppedIndex = indexAt( event->pos() );
        if( !droppedIndex.isValid() )
            return;
    
        QTreeWidget::dropEvent(event);
    
        DropIndicatorPosition dp = dropIndicatorPosition();
        if (dp == QAbstractItemView::BelowItem) {
            droppedIndex = droppedIndex.sibling(droppedIndex.row() + 1, // adjust the row number
                                                droppedIndex.column());
        }
        selectionModel()->select(droppedIndex, QItemSelectionModel::Select);
    }