QTreeWidget拖拽节点
一、前言
在使用QTreeWidget创建树状栏时,期望可以通过拖动节点移动到不同的组,但是组禁止拖动;节点只分为组(父节点)和子项,子项a拖动到另一个组X的子项b时,a作为X的子项,而非b的子项;
二、实现过程
1、定义item的属性,设置到data中,对项的类别作判断
typedef enum
ITEM_MIN,
ITEM_PARENT,
ITEM_SUB,
ITEM_MAX
}TREE_ITEM_ENUM;
2、继承拖拽事件
protected:
//虚函数重载
virtual void contextMenuEvent(QContextMenuEvent *event);
virtual void startDrag(Qt::DropActions supportedActions);
virtual void dropEvent(QDropEvent *event);
virtual void dragEnterEvent(QDragEnterEvent *event);
3、构造时开启拖拽响应属性
setSelectionMode(QAbstractItemView::SingleSelection); //单选
setDragEnabled(true); //启用拖放
setAcceptDrops(true); //设置拖放
setDropIndicatorShown(true); //设置显示将要被放置的位置
setDragDropMode(QAbstractItemView::InternalMove); //设置拖放模式为移动项目,否则为复制项目
setIndentation(20);
//setRootIsDecorated(false);
this->header()->hide();//隐藏头
4、执行拖拽,子项a拖动到子项b时,先找到b的父类,删除a再新建个a(复制数据),设置父类为b的父类
void TreeWidget::dropEvent(QDropEvent *event)
if (event->mimeData()->hasFormat("application/x-qabstractitemmodeldatalist"))
QByteArray itemData = event->mimeData()->data("application/x-qabstractitemmodeldatalist");
QTreeWidgetItem *srcItem = (QTreeWidgetItem*)((void*)QVariant(itemData).toInt());
QTreeWidgetItem *desItem = itemAt(event->pos());
if (desItem == srcItem || desItem == NULL)
event->ignore();
return;
TREE_ITEM_ENUM srcType = (TREE_ITEM_ENUM)srcItem->data(0, Qt::UserRole).toInt();
TREE_ITEM_ENUM desType = (TREE_ITEM_ENUM)desItem->data(0, Qt::UserRole).toInt();
if (srcType == ITEM_SUB)
if(ITEM_PARENT == desType)
QTreeWidget::dropEvent(event);
QTreeWidgetItem *parentItem = desItem->parent();
int index = parentItem->indexOfChild(desItem);
QTreeWidgetItem *item = new QTreeWidgetItem();
item->setData(0, Qt::UserRole, srcItem->data(0, Qt::UserRole));
item->setText(0, srcItem->text(0));
parentItem->insertChild(index, item);
delete srcItem;
srcItem = NULL;
}
5、禁用拖拽组
void TreeWidget::dragEnterEvent(QDragEnterEvent *event)
if (event->mimeData()->hasFormat("application/x-qabstractitemmodeldatalist"))
QByteArray itemData = event->mimeData()->data("application/x-qabstractitemmodeldatalist");
QTreeWidgetItem *srcItem = (QTreeWidgetItem*)((void*)QVariant(itemData).toInt());
int type = srcItem->data(0, Qt::UserRole).toInt();
if(ITEM_PARENT == type)
event->ignore();