Начиная с Qt 5.4 (и я предполагаю, что это было верно даже в Qt 4.8), установка DragDropOverwriteMode
в true
приведет к правильному , что приведет к сбросу перетаскивания только на существующие элементы и предотвратит " выше / ниже пунктов "отбрасывать цели от появления.
Кроме того, в отличие от того, о чем говорится в вопросе, DragDropOverwriteMode
по умолчанию установлено на false
для QTreeView
(я не проверял, может быть, это более новые версии Qt), поэтому его нужно установить на true
вручную.
Однако все же полезно иметь возможность рассчитывать, на какие позиции можно уронить предмет. Например, в QTreeView нельзя перетаскивать перетаскиваемый предмет на левое поле элементов, то есть на красную область ниже:
Если что-то упало в недопустимой красной области, dropMimeData
будет вызываться с аргументом parent
, установленным в NULL
. Так что было бы полезно ignore
dragMoveEvent
заранее, чтобы показать курсор "Вы не можете здесь сбросить" для пользователя , чтобы они знали, что не могут туда попасть. Qt не реализует изменение курсора мыши на недопустимых областях при перетаскивании (по состоянию на Qt 5.4), но мы можем сделать это так:
bool SubclassedTreeView::dropResultsInValidIndex(const QPoint& pos)
{
QTreeWidgetItem* item = itemAt(pos);
if (item == NULL || !indexFromItem(item).isValid())
return false;
return visualRect(indexFromItem(item)).adjusted(-1, -1, 1, 1).contains(pos, false);
}
virtual void SubclassedTreeView::dragMoveEvent(QDragMoveEvent* event)
{
QTreeWidget::dragMoveEvent(event);
if (!event->isAccepted())
return;
if (dropResultsInValidIndex(event->pos()))
event->accept();
else
event->ignore(); //Show 'forbidden' cursor.
}
virtual bool SubclassedTreeView::dropMimeData(QTreeWidgetItem* parent, int index, const QMimeData* data, Qt::DropAction action)
{
Q_UNUSED(index);
//Modify the following action and data format checks to suit your needs:
if (parent == NULL || action != Qt::CopyAction || !data->hasFormat("my/preferred-type"))
return false;
QModelIndex modelIndex = indexFromItem(parent);
//modelIndex is where the data is dropped onto. Implement your custom drop action here...
return true;
}
Приведенный выше код содержит небольшую часть visualRect….adjusted(-1, -1, 1, 1)
, которая была украдена из QAbstractItemViewPrivate::position
источников. Фактически источники этой функции можно использовать для вычисления областей перезаписи / вставки / недействительных элементов, когда QAbstractItemViewPrivate::position
равно false
.