重写QTreeWidget实现节点的拖拽功能

先看效果:

 鼠标拖动操作效果:

 重写QTreeWidget实现节点的拖拽功能_第1张图片

 重写QTreeWidget实现节点的拖拽功能_第2张图片

 重写QTreeWidget实现节点的拖拽功能_第3张图片

重写QTreeWidget实现节点的拖拽功能_第4张图片

 1,重写QTreeWidget类:

QTreeWidget02.h

#pragma once

#include 
#include "ui_QTreeWidget02.h"
#include 
#include 
#include 
#include 
#include 
using namespace std;

class QTreeWidget02 : public QTreeWidget
{
    Q_OBJECT

public:
    QTreeWidget02(QWidget *parent = Q_NULLPTR);

    //声明私有变量m_dragItemVec,用来存储拖拽的节点
	vector 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 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 
#include "Test.h"
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
	Test w;
    w.show();
    return a.exec();
}

你可能感兴趣的:(qt5,qt)