QTreeView - 如何判断 drag/drop 事件是重新排序还是 parents 之间的移动?

QTreeView - how to tell if a drag/drop event is a reorder or a move between parents?

我有 QTreeViewQAbstractItemModel 的子类,目前我正在使用 drag-drop 将项目从一个 parent 索引移动到另一个。我还想添加在同一 parent 索引中重新排列项目顺序的功能。当用户放下一个项目 in-between 两个其他项目时,我需要确定是否应该放下,或者 in-between 它们。我还想在鼠标移动时在两个项目之间画一条黑线,以提示将发生什么,类似于附件中的许多其他 tree-type 视图(例如大多数操作系统上的文件浏览器)图片:

拖入现有项目:

在两个现有项目之间插入:

Qt 会自动执行这部分 drag/drop 行为,还是我必须手动计算鼠标相对于树项边缘的位置?另外,如何在 QTreeView?

中的两个项目之间画一条临时线

前段时间我做了几乎相同的事情,我能想到 3 件事:

这是我正在做的一个非常简单的例子。

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
}

"Bonus" :您可以通过 PrimitiveElement PE_IndicatorItemViewItemDrop 以您自己的风格访问下降指示器。 你可以看看如何自定义它here and here.