QTreeWidget拖拽节点
一、前言
在使用QTreeWidget创建树状栏时,期望可以通过拖动节点移动到不同的组,但是组禁止拖动;节点只分为组(父节点)和子项,子项a拖动到另一个组X的子项b时,a作为X的子项,而非b的子项;
二、实现过程
1、定义item的属性,设置到data中,对项的类别作判断

1 typedef enum 2 { 3 ITEM_MIN, 4 ITEM_PARENT, 5 ITEM_SUB, 6 ITEM_MAX 7 }TREE_ITEM_ENUM;
2、继承拖拽事件

1 protected: 2 //虚函数重载 3 virtual void contextMenuEvent(QContextMenuEvent *event); 4 virtual void startDrag(Qt::DropActions supportedActions); 5 virtual void dropEvent(QDropEvent *event); 6 virtual void dragEnterEvent(QDragEnterEvent *event);
3、构造时开启拖拽响应属性

1 setSelectionMode(QAbstractItemView::SingleSelection); //单选 2 setDragEnabled(true); //启用拖放 3 setAcceptDrops(true); //设置拖放 4 setDropIndicatorShown(true); //设置显示将要被放置的位置 5 setDragDropMode(QAbstractItemView::InternalMove); //设置拖放模式为移动项目,否则为复制项目 6 setIndentation(20); 7 //setRootIsDecorated(false); 8 this->header()->hide();//隐藏头
4、执行拖拽,子项a拖动到子项b时,先找到b的父类,删除a再新建个a(复制数据),设置父类为b的父类

1 void TreeWidget::dropEvent(QDropEvent *event) 2 { 3 if (event->mimeData()->hasFormat("application/x-qabstractitemmodeldatalist")) 4 { 5 QByteArray itemData = event->mimeData()->data("application/x-qabstractitemmodeldatalist"); 6 QTreeWidgetItem *srcItem = (QTreeWidgetItem*)((void*)QVariant(itemData).toInt()); 7 QTreeWidgetItem *desItem = itemAt(event->pos()); 8 9 if (desItem == srcItem || desItem == NULL) 10 { 11 event->ignore(); 12 return; 13 } 14 15 TREE_ITEM_ENUM srcType = (TREE_ITEM_ENUM)srcItem->data(0, Qt::UserRole).toInt(); 16 TREE_ITEM_ENUM desType = (TREE_ITEM_ENUM)desItem->data(0, Qt::UserRole).toInt(); 17 18 if (srcType == ITEM_SUB) 19 { 20 if(ITEM_PARENT == desType) 21 QTreeWidget::dropEvent(event); 22 else 23 { 24 QTreeWidgetItem *parentItem = desItem->parent(); 25 int index = parentItem->indexOfChild(desItem); 26 QTreeWidgetItem *item = new QTreeWidgetItem(); 27 item->setData(0, Qt::UserRole, srcItem->data(0, Qt::UserRole)); 28 item->setText(0, srcItem->text(0)); 29 parentItem->insertChild(index, item); 30 31 delete srcItem; 32 srcItem = NULL; 33 } 34 } 35 } 36 }
5、禁用拖拽组

1 void TreeWidget::dragEnterEvent(QDragEnterEvent *event) 2 { 3 if (event->mimeData()->hasFormat("application/x-qabstractitemmodeldatalist")) 4 { 5 QByteArray itemData = event->mimeData()->data("application/x-qabstractitemmodeldatalist"); 6 QTreeWidgetItem *srcItem = (QTreeWidgetItem*)((void*)QVariant(itemData).toInt()); 7 int type = srcItem->data(0, Qt::UserRole).toInt(); 8 if(ITEM_PARENT == type) 9 event->ignore(); 10 else 11 event->accept(); 12 } 13 else 14 event->ignore(); 15 }
6、运行效果如下
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具