一、前言
在使用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、運行效果如下

