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)
上一篇 2022年9月30日 下午10:36
下一篇 2022年9月30日 下午10:46


相关推荐

  • 深入理解JVM的垃圾回收机制

    深入理解JVM的垃圾回收机制上一篇博客介绍了Java运行时内存的各个区域。对于程序计数器、虚拟机栈、本地方法栈这三个部分而言,其生命周期与相关线程有关,随线程而生,随线程而灭。并且这三个区域的内存分配与回收具有确定性,因为当方法结束或者线程结束时,内存就自然跟着线程回收了。因此本篇文章所讲的有关内存分配和回收关注的是Java堆与方法区这两个区域。1、如何判断对象已“死”Java堆中存放着几乎所有的对象实例,垃圾回收器…

    2022年4月29日
    41
  • java权限拦截器

    java权限拦截器SecurityInterceptor.javapackagelight.mvc.framework.interceptors;importjava.util.List;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;importlight.

    2022年5月29日
    36
  • navicat 15激活码-激活码分享[通俗易懂]

    (navicat 15激活码)好多小伙伴总是说激活码老是失效,太麻烦,关注/收藏全栈君太难教程,2021永久激活的方法等着你。IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.net/100143.html09LVN3XLKC-eyJsaWNlbnNlSWQi…

    2022年3月28日
    1.1K
  • 总结这段时间的学习和生活

    越来越发现自己活的很狭隘,思想也比较狭隘!现在的生活是8点每天早上起床,在家吃个早饭,然后骑车去公司。这几天发现走路去公司也就十几分钟,那就走路吧,走路的时候自己也听一听音乐或者一些线上的音频文件,发现早晨走路还是听舒服的,这样也可以简单的锻炼一下身体,从惠州到长沙,很久没有坚持锻炼了。

    2022年2月26日
    53
  • Verdi基础知识整理

    Verdi基础知识整理Verdi 主要在以下方面使用 Verdi 使用情形 IC 验证工程师 Debug IC 设计工程师 Review 学习目标主要以下三方面 能够生成 fsdb 波形 能够查看 fsdb 波形 能够追踪 RTL 代码 生成 FSDB 波形三个变量 VERDI HOME NOVAS HOME 仿真器默认 且为设置 PATH 做准备 PATH 让系统 Linux 找到 verdiLD LIB

    2026年3月19日
    2
  • Python 快速排序

    Python 快速排序Python 快速排序基本原理 利用递归的思想 在开始的时候选择一个基准值 大于这个基准值的数存放到一个列表中 其他值存放到另一个列表中 然后这两个列表进行递归操作 时间复杂度为 O nlog2n n 为数组的个数 空间复杂度为 O nlog2n 不稳定算法 该图片来源于网络快速排序 defquick sort array 快速排序 para

    2026年3月19日
    1

发表回复

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

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