Qt拖拽事件,实现控件内项的相互拖拽

news2024/9/20 9:02:44

文章目录

  • 1拖拽演示
  • 2 步骤
  • 3 实现

这里主要以QTableview控件为例,实现表格内数据的相互拖拽。

1拖拽演示

在这里插入图片描述

2 步骤

自定以QTableView类,在自定义类中重写拖拽事件:

void dropEvent(QDropEvent *event);
void dragEnterEvent(QDragEnterEvent *event);
void dragMoveEvent(QDragMoveEvent *event);
void dragLeaveEvent(QDragLeaveEvent *event);

实现自定义的QTableView,在鼠标点击项的时候,构造一个图片,模拟出项被拖动的样子,通过
QMimeData来传递数据,QDrag会触发表格的进入事件,在进入事件内出入一个新的项,并通过发送信号的对象,来通过指针删除原来的项,大概思路就是这样。

3 实现

#include <QTableView>
#include <QStandardItemModel>
#include <QDropEvent>
#include <QMouseEvent>
#include <QDragEnterEvent>
#include<QByteArray>
class CTableView : public QTableView
{
	Q_OBJECT

public:
	CTableView(QWidget *parent);
	~CTableView();
public:
	void insertNewItem(QString str);
	void setHorizontalHeaderName(QString _name);
	bool removeItem(QString str);
	void dropEvent(QDropEvent *event);
	void dragEnterEvent(QDragEnterEvent *event);
	void dragMoveEvent(QDragMoveEvent *event);
	void dragLeaveEvent(QDragLeaveEvent *event);
private:

	void slotItemPressed(const QModelIndex &index);
private:
	QStandardItemModel*		m_model;
};
#include "ctableview.h"
#include <QHeaderView>
#include <QPainter>
#include <QMimeData>
#include <QDrag>
#include <QDebug>
CTableView::CTableView(QWidget *parent)
	: QTableView(parent)
{
	setAcceptDrops(true);
	m_model = new QStandardItemModel();
	this->setModel(m_model);
	this->verticalHeader()->setVisible(false);
	this->setEditTriggers(QAbstractItemView::NoEditTriggers);
	connect(this, &CTableView::pressed, this, &CTableView::slotItemPressed);
}

CTableView::~CTableView()
{

}

void CTableView::insertNewItem(QString str)
{
	int t_row = m_model->rowCount();
	QStandardItem* t_item = new QStandardItem(str);
	
	m_model->setItem(t_row, 0, t_item);
	m_model->item(t_row, 0)->setTextAlignment(Qt::AlignHCenter);
	m_model->item(t_row, 0)->setBackground(QColor(187, 203, 233));
}

void CTableView::setHorizontalHeaderName(QString _name)
{
	m_model->setHorizontalHeaderLabels(QStringList(_name));
	this->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);// 设置表头调整模式为 Stretch
	this->horizontalHeader()->setStretchLastSection(true);// 将最后一列拉伸到表格宽度
	this->horizontalHeader()->setStyleSheet("QHeaderView::section {"
		"color: rgb(32,159,223);padding-left: 4px;border: 1px solid #6c6c6c;}");
}


bool CTableView::removeItem(QString str)
{
	for (int row = 0; row < m_model->rowCount(); row++)
	{
		if (m_model->item(row, 0)->text() == str)
		{
			return m_model->removeRow(row);
		}
	}
	return false;
}

void CTableView::dropEvent(QDropEvent *event)
{
	if (!event->mimeData()->hasText()) { // 修改判断条件
		return;
	}
	insertNewItem(event->mimeData()->text());
	CTableView* tableView = qobject_cast<CTableView*>(event->source());
	if (tableView == nullptr)
	{
		return;
	}
	tableView->removeItem(event->mimeData()->text());
}

void CTableView::dragEnterEvent(QDragEnterEvent *event)
{
	//这个函数的主要作用是根据拖动数据中是否包含文本,决定是否接受拖放操作,并将操作类型设置为建议类型。
	if (event->mimeData()->hasText()) { // 修改判断条件
		event->acceptProposedAction();
	}
}


void CTableView::dragMoveEvent(QDragMoveEvent *event)
{
	if (event->mimeData()->hasText()) { // 修改判断条件
		event->acceptProposedAction();
	}
}

void CTableView::dragLeaveEvent(QDragLeaveEvent *event)
{
	Q_UNUSED(event);
}

void CTableView::slotItemPressed(const QModelIndex &index)
{
	if (!index.isValid())
	{
		return;
	}
	QStandardItem* item = m_model->item(index.row(), index.column());
	QPixmap* pixmap = new QPixmap(this->horizontalHeader()->sectionSize(0), this->verticalHeader()->sectionSize(0)); // 创建画布
	pixmap->fill(QColor(187, 203, 233)); // 填充绿色背景
	QPainter t_painter(this); // 创建 QPainter 对象
	t_painter.begin(pixmap);
	t_painter.drawText(QRectF(0, 0, 100, 20), Qt::AlignCenter, item->text()); // 在画布上绘制文字
	t_painter.end();
	QMimeData* t_mimeData = new QMimeData;
	t_mimeData->setText(item->text());
	QPoint hotSpot(pixmap->width() / 2, pixmap->height() / 2); // 设置热点位置为图片中心
	QDrag* t_drag = new QDrag(this);
	t_drag->setMimeData(t_mimeData);
	t_drag->setPixmap(*pixmap);
	t_drag->setHotSpot(hotSpot); // 设置热点位置
	t_drag->exec(Qt::CopyAction | Qt::MoveAction);
	delete t_drag;
	t_drag = nullptr;
	delete pixmap;
	pixmap = nullptr;
}

程序主窗口,new CTableView表格

#include "ctestdragitem.h"
#include <QGridLayout>
const int TableCount = 9;
CTestDragItem::CTestDragItem(QWidget *parent)
	: QWidget(parent)
{
	ui.setupUi(this);
	QGridLayout* gridLayout = new QGridLayout(ui.widget);
	gridLayout->setSpacing(10);
	gridLayout->setContentsMargins(10, 10, 10, 10);

	for (int i=0; i< TableCount; i++)
	{
		CTableView * tableView = new CTableView(ui.widget);
		tableView->setHorizontalHeaderName(QString("table%1").arg(i));
		tableView->insertNewItem(QString("item%1%2").arg(i / 3).arg(i % 3));
		gridLayout->addWidget(tableView, i / 3, i % 3);
	}

}

通过以上方法就可以实现,表格数据的相互拖拽,这里只是举例了简单的用法,更复杂的操作也差不多,需要自己处理逻辑。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1431855.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

装饰你的APP:使用Lottie-Android创建动画效果

装饰你的APP&#xff1a;使用Lottie-Android创建动画效果 1. Lottie-Android简介 Lottie-Android是一个强大的开源库&#xff0c;由Airbnb开发&#xff0c;旨在帮助开发者轻松地在Android应用中添加高质量的动画效果。它基于Adobe After Effects软件中的Bodymovin插件&#x…

一种缩短轮询时间的处理办法

我们平常处理轮询任务的时候&#xff0c;会用时间片的方式来分割开&#xff0c;每个时间片处理某一个任务。 有时候有些任务并不需要有动作&#xff0c;本轮轮询到它&#xff0c;它不需要干活&#xff0c;于是这个时间片就浪费了。但如果其他时间片里面的任务又急着呢&#xff…

微信小程序使用ucharts折线图,有负数显示0刻度线

当数据有负数和正数的时候默认不会显示0刻度线&#xff0c;不方便看出正负对比 实现思路&#xff1a;显示的刻度线是根据数据的最大值和最小值自动分配到刻度线上面&#xff0c;把最大值和最小值设置为一样&#xff0c;然后平均分配给五个刻度线中间的刻度线就会为0就实现了显…

深入理解Istio服务网格(一)数据平面Envoy

一、服务网格概述(service mesh) 在传统的微服务架构中&#xff0c;服务间的调用&#xff0c;业务代码需要考虑认证、熔断、服务发现等非业务能力&#xff0c;在某种程度上&#xff0c;表现出了一定的耦合性 服务网格追求高级别的服务流量治理能力&#xff0c;认证、熔断、服…

如何在Vue应用程序中使用Vue-Router来实现路由嵌套动画效果

Vue-Router是Vue.js官方的路由管理插件&#xff0c;可以帮助我们轻松管理应用程序的路由。除了基本的路由功能外&#xff0c;Vue-Router还允许我们在切换路由时添加动画效果&#xff0c;提升用户体验。本文将介绍如何使用Vue-Router来实现路由嵌套动画效果&#xff0c;并提供具…

跟着pink老师前端入门教程-day17

2、CSS3 动画 动画&#xff08;animation&#xff09;是CSS3中就要有颠覆性的特征之一&#xff0c;可通过设置多个节点来精确控制一个或一组动画&#xff0c;常用来实现复杂的动画效果 相比较过渡&#xff0c;动画可以实现更多变化&#xff0c;更多控制&#xff0c;连续自动播…

Python3 交叉编译 numpy pandas scipy scikit-learn

1. 概述 由于需要将Python3.7 和一些软件包交叉编译到 armv7 平台硬件&#xff0c;如果是arm64位的系统&#xff0c;很多包都有预编译好的版本&#xff0c;可直接下载。本文主要在基于 crossenv(https://github.com/benfogle/crossenv)环境下交叉编译。 2. 编译环境搭建 创建…

处理SERVLET中的错误

处理SERVLET中的错误 问题陈述 一位用户在使用在线计算机应用程序时输入一个非数字字符做数字加法。servlet试图将用户输入的值转换成整数型时,引发了NumberFormException类型的异常。要创建一个Web应用程序来使用自定义错误页面处理该异常。该自定义错误页面需要向用户提供关…

【原创】点火线圈项目

一、项目介绍 此点火线圈项目主要实现对各部件的自动组装、测试、以及下料。 二、各个工位实现动作流程 1、合装移载位,这个工位通过伺服电机和气缸夹爪把上游设备加工的点火线圈插头移载到合装位。 通过伺服设置抓料位置(绝对定位)伺服电机到了抓料位后伸出气缸伸出,夹…

acwing869. 试除法求约数870. 约数个数AcWing871. 约数之和872. 最大公约数

869. 试除法求约数 思路&#xff1a; 约数和质数的求解有着共性&#xff0c; 就是都是使用 for (int i 1; i < n/i; i) 进行计算的。这样的原因是因为约数必然也是两两一组&#xff0c; 那么我们求出小的自然也就知道另一个&#xff0c;只要再判断一下n/i和i是否相同&a…

Qt PCL学习(一):环境搭建

参考 (QT配置pcl)PCL1.12.1QT5.15.2vs2019cmake3.22.4vtk9.1.0visual studio2019Qt5.15.2PCL1.12.1vtk9.1.0cmake3.22.2 本博客用到的所有资源 版本一览&#xff1a;Visual Studio 2019 Qt 5.15.2 PCL 1.12.1 VTK 9.1.0https://pan.baidu.com/s/1xW7xCdR5QzgS1_d1NeIZpQ?pw…

队列---数据结构

定义 队列&#xff08;Queue&#xff09;简称队&#xff0c;也是一种操作受限的线性表&#xff0c;只允许在表的一端进行插入&#xff0c;而在表的另一端进行删除。向队列中插入元素称为入队或进队&#xff1b;删除元素称为出队或离队。 队头&#xff08;Front&#xff09;&a…

小米平板6获取root权限教程

1. 绑定账号 1> 打开"设置-我的设备-全部参数-连续点击MIUI版本按钮"&#xff0c;直到提示已打开开发者模式( p s : 这里需要重点关注红框平板型号和 M I U I 版本&#xff0c;例如我这里平板型号是 X i a o m i P a d 6 &#xff0c; M I U I 版本是 14.0.10 &am…

3 编辑器(Vim)

1.完成 vimtutor。备注&#xff1a;它在一个 80x24&#xff08;80 列&#xff0c;24 行&#xff09; 终端窗口看起来效果最好。 2.下载我们提供的 vimrc&#xff0c;然后把它保存到 ~/.vimrc。 通读这个注释详细的文件 &#xff08;用 Vim!&#xff09;&#xff0c; 然后观察 …

MySQL数据库①_MySQL入门(概念+使用)

目录 1. 数据库的概念 1.1 数据库的存储介质 1.2 主流数据库 2. MySQL的基本使用 2.1 链接数据库 2.2 服务器管理 2.3 数据库&#xff0c;服务器和表关系 2.4 简单MySQL语句 3. MySQL架构 4. SQL分类 5. 存储引擎 本篇完。 1. 数据库的概念 数据库是按照数据结构来…

智能决策的艺术:探索商业分析的最佳工具和方法

文章目录 一、引言二、商业分析思维概述三、数据分析在商业实践中的应用四、如何培养商业分析思维与实践能力五、结论《商业分析思维与实践&#xff1a;用数据分析解决商业问题》亮点内容简介作者简介目录获取方式 一、引言 随着大数据时代的来临&#xff0c;商业分析思维与实…

Cox等级资料是个坑

R语言做&#xff01;初学者先进来看看&#xff01;&#xff01;&#xff01; SCI冲 COX多因素模型需要满足的条件&#xff1a; 1.各观测值间相互独立&#xff0c;即残差之间不存在自相关&#xff1b; 2.因变量和自变量之间存在线性关系&#xff1b; 3.残差的方差齐&#xf…

蓝桥杯备战——12.超声波与测频代码优化

1.优化分析 昨天我在看原理图的发现超声波模块的反馈引脚P11刚好可以使用PCA模块0的捕获功能&#xff0c;我就想着把PCA功能留给超声波&#xff0c;然后测频功能还是改成定时器0来完成&#xff0c;然后前后台功能改成定时器1。 至于我为什么要这么改呢&#xff0c;看一下我原…

【2024美赛】C题 Problem C: Momentum in Tennis网球运动中的势头 网球问题一python代码

相关链接 &#xff08;1&#xff09;问题分析 &#xff08;2&#xff09;26页论文 1 题目 http://t.csdnimg.cn/BzhFu 2 问题一数学模型 采用隐马尔可夫模型&#xff08;Markov Model&#xff09;&#xff0c;这是一种描述随机过程的数学模型&#xff0c;它满足马尔可夫性…

Powershell Install 一键部署Prometheus

前言 Prometheus是一个开源的系统监控和报警系统,现在已经加入到CNCF基金会,成为继k8s之后第二个在CNCF托管的项目,在kubernetes容器管理系统中,通常会搭配prometheus进行监控,同时也支持多种exporter采集数据,还支持pushgateway进行数据上报,Prometheus性能足够支撑上…