У меня есть подклассы QTreeView
а также QAbstractItemModel
и в настоящее время я использую drag-drop для перемещения элементов из одного родительского индекса в другой. Я хочу также добавить возможность изменить порядок элементов в пределах того же родительского индекса. Когда пользователь отбрасывает элемент между двумя другими элементами, мне нужно определить, должно ли быть перетаскивание между ними. Я также хотел бы нарисовать темную линию между двумя элементами при перемещении мыши, чтобы намекнуть, что произойдет, подобно многим другим представлениям древовидного типа (например, исследователям файлов в большинстве операционных систем), как на прилагаемых рисунках:
Перетащите в существующий элемент:
Вставьте между двумя существующими элементами:
Автоматизирует ли Qt эту часть поведения перетаскивания, или мне нужно вручную вычислять положение мыши относительно края элемента дерева? Кроме того, как я могу нарисовать временную линию между двумя элементами в QTreeView
?
Я сделал почти то же самое некоторое время назад, и я могу думать о 3 вещах:
dropEvent()
и, возможно, ваш dragMoveEvent()
;Вот очень минимальный пример того, что я делал.
в dragMoveEvent()
Я показывал индикатор падения. Таким образом, при перетаскивании объекта всегда будет отображаться индикатор падения.
void MyTreeView::dragMoveEvent(QDragMoveEvent* event)
{
setDropIndicatorShown(true);
QTreeView::dragMoveEvent(event);
}
в dropEvent()
Я управлял каждым делом, то есть был ли элемент, который я перетаскивал, другим элементом, над ним, под ним или в окне просмотра. Затем, в соответствии с этим, я управлял собственным падением, а в конце события я скрывал индикатор сброса.
void MyTreeView::dropEvent(QDropEvent* event)
{
bool dropOK = false;
DropIndicatorPosition dropIndicator = dropIndicatorPosition();
switch (dropIndicator)
{
case QAbstractItemView::AboveItem:
dropOK = true;
break;
case QAbstractItemView::BelowItem:
dropOK = true;
break;
case QAbstractItemView::OnItem:
dropOK = false;
break;
case QAbstractItemView::OnViewport:
dropOK = false;
break;
}
if(dropOK)
{
// Here, you need to manage yourself the case of dropping an item
}
setDropIndicatorShown(false); // hide the drop indicator once the drop is done
}
«Бонус» : вы можете получить доступ к индикатору падения в своем собственном стиле с помощью PrimitiveElement PE_IndicatorItemViewItemDrop
,
Вы можете увидеть, как настроить его Вот а также Вот.
Других решений пока нет …