Qt中自定义QTreeWidget实现节点拖拽复制功能

QT中在QWidget支持拖拽功能,QTreeWidget继承自QWidget,所以自然也具有节点的拖拽功能。

拖拽包含两个功能:一个是拖动(Drag),一个是放下(Drop)。拖动的数据是QMimeData数据,MIME数据定义格式:类型/数据 (注意中间有斜线)。

若被拖动的对象放下的控件,不接受拖动的对象,Qt光标显示禁用的形状(一个禁用形状)。

开始拖动:通过调用QDrag::exec()函数启动,该函数是一个阻塞函数(但不会阻塞主事件循环),这意味着在拖放操作结束之前,不会返回该函数;通过调用setAcceptDrops()函数可设置控件是否接受放下事件。
QDragEnterEvent:拖动进入事件
QDragMoveEvnet:拖动移动事件
QDropEvent:放下事件
QDragLeaveEvent:当拖放操作离开控件时发送该事件

下面是一个实例,在树形控件中,拖动节点,并且被拖动的内容放大显示:
在这里插入图片描述

拖动的TreeWidget:

#pragma once

#include <QTreeWidget>

class QMouseEvent;
class QTreeWidgetItem;

class DragTreeWidget : public QTreeWidget {
	Q_OBJECT

public:
	DragTreeWidget(QWidget *parent);
	~DragTreeWidget();

private:
	void init();
private:

	virtual void mousePressEvent(QMouseEvent *event)override;

private:
	QTreeWidgetItem* _selectItem = nullptr;
};
#include "DragTreeWidget.h"

#include <QMouseEvent>
#include <QTreeWidgetItem>
#include <QByteArray>
#include <QDataStream>
#include <QMimeData>
#include <QDrag>
#include "QtGuiDrag.h"

DragTreeWidget::DragTreeWidget(QWidget *parent)
	: QTreeWidget(parent) {
	init();
	setDragDropMode(QAbstractItemView::InternalMove);
	setDragEnabled(true);
}

DragTreeWidget::~DragTreeWidget() {

}

void DragTreeWidget::init() {
	QTreeWidgetItem* topItem = new QTreeWidgetItem(this);
	topItem->setText(0, QStringLiteral("阳光小区"));
	QTreeWidgetItem* item1 = new QTreeWidgetItem(topItem);
	item1->setText(0, QStringLiteral("王天天"));
	QTreeWidgetItem* item2 = new QTreeWidgetItem(topItem);
	item2->setText(0, QStringLiteral("刘一一"));
	topItem->setExpanded(true);

	QTreeWidgetItem* topItem2 = new QTreeWidgetItem(this);
	topItem2->setText(0, QStringLiteral("幸福小区"));
	QTreeWidgetItem* item3 = new QTreeWidgetItem(topItem2);
	item3->setText(0, QStringLiteral("赵鑫"));
	QTreeWidgetItem* item4 = new QTreeWidgetItem(topItem2);
	item4->setText(0, QStringLiteral("王旭"));
	topItem2->setExpanded(true);
}

void DragTreeWidget::mousePressEvent(QMouseEvent *event) {
	if (event->button()&Qt::LeftButton){
		_selectItem = itemAt(event->pos());

		QByteArray dataItem;
		QDataStream dataStream(&dataItem, QIODevice::WriteOnly);
		dataStream << _selectItem->text(0);

		QMimeData* mimeData = new QMimeData;
		mimeData->setData("Data/name", dataItem);

		QtGuiDrag* dragPiamap = new QtGuiDrag(nullptr);
		dragPiamap->setShowText(_selectItem->text(0));
		QPixmap pixmap = dragPiamap->grab();

		QDrag* drag = new QDrag(this);
		drag->setPixmap(pixmap);
		drag->setMimeData(mimeData);
		drag->setHotSpot(QPoint(pixmap.width() / 2, pixmap.height() / 2));

		drag->exec(Qt::MoveAction);
	}
	QTreeWidget::mousePressEvent(event);
}

放下的TreeWidget

#pragma once

#include <QTreeWidget>

class DropTreeWidget : public QTreeWidget {
	Q_OBJECT

public:
	DropTreeWidget(QWidget *parent);
	~DropTreeWidget();

	void dragEnterEvent(QDragEnterEvent *event)override;
	void dropEvent(QDropEvent *event)override;
private:
	void init();
};

#include "DropTreeWidget.h"
#include <QTreeWidgetItem>
#include <QDragEnterEvent>
#include <QDropEvent>
#include <QMimeData>

DropTreeWidget::DropTreeWidget(QWidget *parent)
	: QTreeWidget(parent) {
	init();
}

DropTreeWidget::~DropTreeWidget() {
}

void DropTreeWidget::dragEnterEvent(QDragEnterEvent *event) {
	if (event->mimeData()->hasFormat("Data/name")){
		if (event->source() == this){
			event->setDropAction(Qt::MoveAction);
			event->accept();
		} else {
			event->acceptProposedAction();
		}
	} else {
		event->ignore();
	}
}

void DropTreeWidget::dropEvent(QDropEvent *event) {
	if (event->mimeData()->hasFormat("Data/name")) {
		//获取拖拽时设置的数据
		QByteArray itemData = event->mimeData()->data("Data/name");
		QDataStream dataStream(&itemData, QIODevice::ReadOnly);

		QString text;
		dataStream >>text;

		QTreeWidgetItem *item = itemAt(event->pos()); //当前位置的item
		if (item == nullptr) { 
			return;
		}
		QTreeWidgetItem* newItem = new QTreeWidgetItem(item);
		newItem->setText(0, text);
		item->setExpanded(true);

		if (event->source() == this) {
			event->setDropAction(Qt::MoveAction);
			event->accept();
		} else {
			event->acceptProposedAction();
		}
	} else {
		event->ignore();
	}
}

void DropTreeWidget::init() {
	setDragDropMode(QAbstractItemView::InternalMove);

	QTreeWidgetItem* topItem = new QTreeWidgetItem(this);
	topItem->setText(0, QStringLiteral("一班"));

	QTreeWidgetItem* topItem1 = new QTreeWidgetItem(this);
	topItem1->setText(0, QStringLiteral("二班"));
}

拖动时显示的图片界面:

#pragma once

#include <QWidget>
#include "ui_QtGuiDrag.h"

//拖动时的图片显示

class QtGuiDrag : public QWidget {
	Q_OBJECT

public:
	QtGuiDrag(QWidget *parent = Q_NULLPTR);
	~QtGuiDrag();

	void setShowText(QString text);
private:
	Ui::QtGuiDrag ui;
};

#include "QtGuiDrag.h"

QtGuiDrag::QtGuiDrag(QWidget *parent)
	: QWidget(parent) {
	ui.setupUi(this);

	this->setWindowFlags(Qt::FramelessWindowHint);
	this->setAttribute(Qt::WA_TranslucentBackground, true);
}

QtGuiDrag::~QtGuiDrag() {
}

void QtGuiDrag::setShowText(QString text) {
	ui.label->setText(text);
}

在这里插入图片描述

aaa

  • 3
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wb175208

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值