QTreeWidgetItem得自由移动
QTreeWidget属性
QTreeWidget具备节点拖动属性、同时其也可以限定拖动区域和范围。属性设置如下:
this->setDragEnabled(true); //开启拖拽
this->setDragDropMode(QAbstractItemView::InternalMove);//限定拖拽在内部
this->setDefaultDropAction(Qt::MoveAction);//设置移动模式
this->setAcceptDrops(true);
this->setMouseTracking(true);
item移动
利用QTreeWidget属性设置我们已经能够实现树下节点得移动、但是这些移动基本上无序的。若想实现固定节点下的item移动需要了解树得层级结构以及树得事件。
QTreeWidget事件
- dragEnterEvent(QDragEnterEvent *event);
鼠标拖进事件 - dragMoveEvent(QDragMoveEvent *event);
拖动事件 - dragLeaveEvent(QDragLeaveEvent *event);
释放事件 - dropEvent(QDropEvent *event)
拖放事件
功能实现
对于节点得拖动更多的使用场景是想通过拖动实现某一功能,再次我们将实现再某一节点下得item可以通过拖动实现排序而且仅限于当前节点下。
重写dropEvent(QDropEvent *event)
重写目的在于找到我们拖放得item是节点中的那个、需要确定他的位置。这里用到了QDragMoveEvent事件、利用鼠标坐标寻找Mytree当前坐标得item。
void MyTree::dropEvent(QDropEvent *event)
{
QDragMoveEvent *mouseEvent = (QDragMoveEvent*)event;
QTreeWidgetItem *item = Mytree->itemAt(mouseEvent->pos());
if(item == nullptr) {
qInfo("[%s] -- n_EventType_Move == nullptr");
return false;
}
STRCT_TreeItemInfo strctTreeItemInfo;
strctTreeItemInfo = item->data(colItem, Qt::UserRole).value<STRCT_TreeItemInfo>();
//return false 就可以自主控制插入顺序了
return AllDropTop(item);
}
在这里需要注意、如果你不介意拖动的item释放到其他item得上方或者下方。dropEvent事件可以返回true,如果该事件返回false。则无法拖动成功。
在这里我们想限定他的拖动规则、只想拖动以后item永远插入到其他item得上方。需要其他功能实现。
AllDropTop
bool Mytree::AllDropTop(QTreeWidgetItem *item)
{
//处理拖动前和拖动后是否还在同一节点下。就需要比较前后父级是否还是同一个。
QTreeWidgetItem* qCurent = Mytree->currentItem()->parent();
QTreeWidgetItem* parentItem = item->parent();
if(qCurent == parentItem) {
//删除该节点下移动item得源数据
qCurent->removeChild(qCurent1);
//得到移动后的位置
int index = qCurent->indexOfChild(item);
//再移动后的位置上插入原来的数据
qCurent->insertChild(index, qCurent1);
return false;
} else {
return false;
}
}