先看效果:
鼠标拖动操作效果:
1,重写QTreeWidget类:
QTreeWidget02.h
#pragma once
#include <QtWidgets/QWidget>
#include "ui_QTreeWidget02.h"
#include <vector>
#include <iostream>
#include <QtWidgets/QTreeWidget>
#include <QtWidgets/QTreeWidgetItem>
#include <QDragEnterEvent>
using namespace std;
class QTreeWidget02 : public QTreeWidget
{
Q_OBJECT
public:
QTreeWidget02(QWidget *parent = Q_NULLPTR);
//声明私有变量m_dragItemVec,用来存储拖拽的节点
vector<QTreeWidgetItem*> m_dragItemVec;
//重写拖拽函数
virtual void dragEnterEvent(QDragEnterEvent *ev);
virtual void dragMoveEvent(QDragMoveEvent * ev);
virtual void dropEvent(QDropEvent *ev);
private:
Ui::QTreeWidget02Class ui;
};
QTreeWidget02..cpp
#include "QTreeWidget02.h"
QTreeWidget02::QTreeWidget02(QWidget *parent)
: QTreeWidget(parent)
{
ui.setupUi(this);
//按 ctrl 或 shift 多选
this->setSelectionMode(QAbstractItemView::ExtendedSelection);
//设置可拖拽性质
this->setDefaultDropAction(Qt::MoveAction);
this->setDragDropMode(QAbstractItemView::DragDrop);
}
//对于dragEnterEvent,将选中的items存进私有变量m_dragItemVec
void QTreeWidget02::dragEnterEvent(QDragEnterEvent *ev)
{
ev->setDropAction(Qt::MoveAction);
QList<QTreeWidgetItem*> selectedItem = selectedItems();
m_dragItemVec.clear();
for (int i = 0; i < selectedItem.size(); i++)
{
if (selectedItem[i] && selectedItem[i]->parent())
{
m_dragItemVec.push_back(selectedItem[i]);
}
}
if (m_dragItemVec.size() > 0)
{
ev->acceptProposedAction();
QTreeWidget::dragEnterEvent(ev);
return;
}
ev->ignore();
QTreeWidget::dragEnterEvent(ev);
}
//对于dragMoveEvent,在这里设置可拖拽区域
void QTreeWidget02::dragMoveEvent(QDragMoveEvent * ev)
{
ev->setDropAction(Qt::MoveAction);
QTreeWidgetItem* itemOver = itemAt(ev->pos());
//设置可拖拽区域
if (itemOver != NULL && itemOver->parent() != NULL)
{
ev->acceptProposedAction();
QTreeWidget::dragMoveEvent(ev);
return;
}
ev->ignore();
QTreeWidget::dragMoveEvent(ev);
}
//对于dropEvent,在这里插入拖拽节点
void QTreeWidget02::dropEvent(QDropEvent *ev)
{
QTreeWidgetItem* itemOver = itemAt(ev->pos());
// if (itemOver == NULL)
// {
// itemOver = new QTreeWidgetItem(this);
// }
//
if ( itemOver != NULL && itemOver->parent())
{
//在此可以对m_dragItemVec做你想做的事
QTreeWidget::dropEvent(ev);
setCurrentItem(itemOver); // 设置为当前选中
itemOver->setExpanded(true);
return;
}
ev->ignore();
QTreeWidget::dropEvent(ev);//如果不符合拖拽要求,这句可以注释掉
}
测试类:
Test.h
class Test : public QWidget
{
Q_OBJECT
public:
Test(QWidget *parent = Q_NULLPTR);
~Test();
private:
//树控件
QTreeWidget02 * m_Treewidget;
//主布局
QVBoxLayout * m_Layout;
private:
//初始化布局
QLayout * InitLayout();
//初始化树控件
void InitQTreeWidgetTest();
};
Test.cpp
#include "Test.h"
Test::Test(QWidget *parent) : QWidget(parent)
{
//设置窗口标题
setWindowTitle(QString::fromLocal8Bit("树控件拖拽"));
//设置窗口大小
resize(800, 600);
//设置窗口布局
setLayout(InitLayout());
InitQTreeWidgetTest();
}
Test::~Test()
{
}
//初始化布局
QLayout * Test::InitLayout()
{
m_Layout = new QVBoxLayout(this);
m_Treewidget = new QTreeWidget02(this);
//设置布局边距
m_Layout->setContentsMargins(0, 0, 0, 0);
//隐藏头
m_Treewidget->setHeaderHidden(true);
m_Layout->addWidget(m_Treewidget);
return m_Layout;
}
//初始化树控件
void Test::InitQTreeWidgetTest()
{
for (int i = 0; i < 2; ++i)
{
QTreeWidgetItem * item = new QTreeWidgetItem(m_Treewidget, QStringList(QString::fromLocal8Bit("父节点%1").arg(i)));
for (int j = 0; j < 3; ++j)
{
QTreeWidgetItem * child = new QTreeWidgetItem(item, QStringList(QString::fromLocal8Bit("%1::子节点%2").arg(i).arg(j)));
}
}
//默认展开所有节点
m_Treewidget->expandAll();
}
main.cpp
#include "QTreeWidget02.h" #include <QtWidgets/QApplication> #include "Test.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); Test w; w.show(); return a.exec(); }