QTreeView — как узнать, является ли событие перетаскивания перестановкой или перемещением между родителями?

У меня есть подклассы QTreeView а также QAbstractItemModel и в настоящее время я использую drag-drop для перемещения элементов из одного родительского индекса в другой. Я хочу также добавить возможность изменить порядок элементов в пределах того же родительского индекса. Когда пользователь отбрасывает элемент между двумя другими элементами, мне нужно определить, должно ли быть перетаскивание между ними. Я также хотел бы нарисовать темную линию между двумя элементами при перемещении мыши, чтобы намекнуть, что произойдет, подобно многим другим представлениям древовидного типа (например, исследователям файлов в большинстве операционных систем), как на прилагаемых рисунках:

Перетащите в существующий элемент:

перетащить в

Вставьте между двумя существующими элементами:

перетащить между

Автоматизирует ли Qt эту часть поведения перетаскивания, или мне нужно вручную вычислять положение мыши относительно края элемента дерева? Кроме того, как я могу нарисовать временную линию между двумя элементами в QTreeView?

3

Решение

Я сделал почти то же самое некоторое время назад, и я могу думать о 3 вещах:

  • вам придется переопределить ваш dropEvent()и, возможно, ваш dragMoveEvent();
  • чтобы проверить, куда вы бросаете предмет, используйте dropIndicatorPosition ();
  • чтобы показать индикатор падения, используйте setDropIndicatorShown (BOOL).

Вот очень минимальный пример того, что я делал.

в 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,
Вы можете увидеть, как настроить его Вот а также Вот.

3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]