Qt中自定义QTreeWidget实现节点拖拽复制功能[通俗易懂]

Qt中自定义QTreeWidget实现节点拖拽复制功能[通俗易懂]QT中在QWidget支持拖拽功能,QTreeWidget继承自QWidget,所以自然也具有节点的拖拽功能。拖拽包含两个功能:一个是拖动(Drag),一个是放下(Drop)。拖动的数据是QMimeData数据,MIME数据定义格式:类型/数据(注意中间有斜线)。若被拖动的对象放下的控件,不接受拖动的对象,Qt光标显示禁用的形状(一个禁用形状)。开始拖动:通过调用QDrag::exec()…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/187311.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号