QTreeWidget拖拽节点

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();