一、前言

在使用QTreeWidget创建树状栏时,期望可以通过拖动节点移动到不同的组,但是组禁止拖动;节点只分为组(父节点)和子项,子项a拖动到另一个组X的子项b时,a作为X的子项,而非b的子项;

二、实现过程

1、定义item的属性,设置到data中,对项的类别作判断

python QTreeWidget 设置在父节点内拖拽排序不改变父节点 qtreewidgetitem拖拽_Qt

python QTreeWidget 设置在父节点内拖拽排序不改变父节点 qtreewidgetitem拖拽_拖拽_02

1 typedef enum
3     ITEM_MIN,
4     ITEM_PARENT,
5     ITEM_SUB,
6     ITEM_MAX
7 }TREE_ITEM_ENUM;

项类别定义

2、继承拖拽事件

python QTreeWidget 设置在父节点内拖拽排序不改变父节点 qtreewidgetitem拖拽_Qt

python QTreeWidget 设置在父节点内拖拽排序不改变父节点 qtreewidgetitem拖拽_拖拽_02

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、构造时开启拖拽响应属性

python QTreeWidget 设置在父节点内拖拽排序不改变父节点 qtreewidgetitem拖拽_Qt

python QTreeWidget 设置在父节点内拖拽排序不改变父节点 qtreewidgetitem拖拽_拖拽_02

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的父类

python QTreeWidget 设置在父节点内拖拽排序不改变父节点 qtreewidgetitem拖拽_Qt

python QTreeWidget 设置在父节点内拖拽排序不改变父节点 qtreewidgetitem拖拽_拖拽_02

1 void TreeWidget::dropEvent(QDropEvent *event)
 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());
 9         if (desItem == srcItem || desItem == NULL)
10         {
11             event->ignore();
12             return;
13         }
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();
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);
31                 delete srcItem;
32                 srcItem = NULL;
33             }
34         }
35     }
36 }

执行拖拽事件

5、禁用拖拽组

python QTreeWidget 设置在父节点内拖拽排序不改变父节点 qtreewidgetitem拖拽_Qt

python QTreeWidget 设置在父节点内拖拽排序不改变父节点 qtreewidgetitem拖拽_拖拽_02

1 void TreeWidget::dragEnterEvent(QDragEnterEvent *event)
 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、运行效果如下


python QTreeWidget 设置在父节点内拖拽排序不改变父节点 qtreewidgetitem拖拽_父类_11



java 正则表达式获取大括号中的数字

1.正则表达式中的圆括号的作用是对字符进行分组,并保存匹配的文本。 2.圆括号用法I:对字符或元字符进行分组,这样在圆括号内就可以对字符组合使用限定符。 eg. 匹配A+一个数字+A+一个数字:(A\d){2} 3.圆括号用法II:表示可选择性。 3.1 从两个直接量中选择一个 eg. gr(a|e)y匹配gray和grey,该例子还可以使用gr[ae]y,字符类效率