QTreeView - 如何判断 drag/drop 事件是重新排序还是 parents 之间的移动?
QTreeView - how to tell if a drag/drop event is a reorder or a move between parents?
我有 QTreeView
和 QAbstractItemModel
的子类,目前我正在使用 drag-drop 将项目从一个 parent 索引移动到另一个。我还想添加在同一 parent 索引中重新排列项目顺序的功能。当用户放下一个项目 in-between 两个其他项目时,我需要确定是否应该放下,或者 in-between 它们。我还想在鼠标移动时在两个项目之间画一条黑线,以提示将发生什么,类似于附件中的许多其他 tree-type 视图(例如大多数操作系统上的文件浏览器)图片:
拖入现有项目:
在两个现有项目之间插入:
Qt 会自动执行这部分 drag/drop 行为,还是我必须手动计算鼠标相对于树项边缘的位置?另外,如何在 QTreeView
?
中的两个项目之间画一条临时线
前段时间我做了几乎相同的事情,我能想到 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
}
"Bonus" :您可以通过 PrimitiveElement PE_IndicatorItemViewItemDrop
以您自己的风格访问下降指示器。
你可以看看如何自定义它here and here.
我有 QTreeView
和 QAbstractItemModel
的子类,目前我正在使用 drag-drop 将项目从一个 parent 索引移动到另一个。我还想添加在同一 parent 索引中重新排列项目顺序的功能。当用户放下一个项目 in-between 两个其他项目时,我需要确定是否应该放下,或者 in-between 它们。我还想在鼠标移动时在两个项目之间画一条黑线,以提示将发生什么,类似于附件中的许多其他 tree-type 视图(例如大多数操作系统上的文件浏览器)图片:
拖入现有项目:
在两个现有项目之间插入:
Qt 会自动执行这部分 drag/drop 行为,还是我必须手动计算鼠标相对于树项边缘的位置?另外,如何在 QTreeView
?
前段时间我做了几乎相同的事情,我能想到 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
}
"Bonus" :您可以通过 PrimitiveElement PE_IndicatorItemViewItemDrop
以您自己的风格访问下降指示器。
你可以看看如何自定义它here and here.