Qt DragDrop拖动与放置
本文章从属于 Qt实验室-CSDN博客系列
拖放操作包括两个动作:拖动(drag)和放下(drop或称为放置)。
拖动允许
对于要拖出的窗口或控件,要setDragEnabled(true)
对于要拖入的窗口或控件,要setAcceptDrops(true)
下面以一个具体的用例进行说明
拖动列表控件中的项目
该用例实现从左边的列表窗口拖出,到右边的Widget窗口拖入
主界面设置
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent)
{this->resize(1200,800);//从ProjectListWidget拖动到MyWidget上QSplitter* center=new QSplitter;center->addWidget(new ProjectListWidget);center->addWidget(new MyWidget);center->setOrientation(Qt::Horizontal);this->setCentralWidget(center);
}
左侧列表窗口设置
class ProjectListWidget : public QListWidget
{Q_OBJECT
public:ProjectListWidget();// QAbstractItemView interface
protected:void startDrag(Qt::DropActions supportedActions);
};
左侧窗口允许拖动其item,并且将item中的文字存入QMimeData,用以传输到右侧窗体中
ProjectListWidget::ProjectListWidget()
{this->addItem("item1");this->addItem("item2");//(1)开启允许拖动,如果不开启是不会有拖动item移动的效果的this->setDragEnabled(true);
}//(2)开始拖动,设置了一种标记为x1的拖动数据
void ProjectListWidget::startDrag(Qt::DropActions supportedActions)
{QString text=this->currentItem()->text();QMimeData* mimeData=new QMimeData;mimeData->setData("x1",text.toLocal8Bit());QDrag* drag=new QDrag(this);drag->setMimeData(mimeData);drag->exec();
}
右侧窗体的实现会多些,首先必须允许拖拽进入事件dragEnterEvent,然后必须允许拖拽移动事件dragMoveEvent。最后实现dropEvent来接收数据。
MyWidget::MyWidget(QWidget *parent): QWidget{parent}
{//(1)开启允许放置,如果不开启,拖动进入界面时将显示禁止符号this->setAcceptDrops(true);
}//(2)实现了以下两个方法后,该界面就能允许拖拽进入了
//对一种被标记为x1的拖动数据允许拖拽进入
void MyWidget::dragEnterEvent(QDragEnterEvent *event)
{if (event->mimeData()->hasFormat("x1"))event->accept();elseevent->ignore();
}void MyWidget::dragMoveEvent(QDragMoveEvent *event)
{if (event->mimeData()->hasFormat("x1"))event->accept();elseevent->ignore();
}//(3)实现dropEvent来接收拖动携带的数据
void MyWidget::dropEvent(QDropEvent *event)
{if (event->mimeData()->hasFormat("x1")){QString text(event->mimeData()->data("x1"));QPoint pos=event->pos();//在这里将拖动过来的数据放入list,然后通过paintEvent()进行绘制m_textList.append({text,pos});event->accept();this->update();}elseevent->ignore();
}void MyWidget::paintEvent(QPaintEvent *event)
{QPainter painter(this);for(int i=0;i<m_textList.size();i++){QPoint pos=m_textList.at(i).second;QString text=m_textList.at(i).first;painter.drawText(pos,text);}
}
最终的效果如下

事件发出顺序和传递规则

上图参考自 Qt拖放(1):拖放基本原理(QDrag类)-CSDN博客
关于 QDrag.exec()
void ProjectListWidget::startDrag(Qt::DropActions supportedActions)
{//调用该方法的时机,点击item并移动鼠标,即进入该方法//然后执行到drag->exec()阻塞//exec()函数是一个阻塞函数(但不会阻塞主事件循环)//也就是说,在松开鼠标之前,不会打印"after drag"//但是窗口依然可以得到其他的事件响应,例如mainwindow依然可以响应QTimer触发的update()QString text=this->currentItem()->text();QMimeData* mimeData=new QMimeData;mimeData->setData("x1",text.toLocal8Bit());QDrag* drag=new QDrag(this);drag->setMimeData(mimeData);qDebug()<<"before drag";drag->exec();qDebug()<<"after drag";
}
MainWindow中构造时添加如下代码,
QTimer* timer=new QTimer(this);timer->setInterval(1000);connect(timer,&QTimer::timeout,[=]{qDebug()<<"update...";this->update();});timer->start();
测试在拖拽中不释放鼠标时,主窗口能否响应其他的事件(是可以的)
bool MainWindow::event(QEvent *event)
{qDebug()<<"event::"<<event;return QMainWindow::event(event);
}
拖动Widget中的内容到另外一个窗口或控件
以上示例开启拖动的时机在startDrag()方法内,QListWidget::startDrag()可以供重写使用,但是对于普通的QWidget来说,并没有该方法可用
本示例以一个继承自QWidget的LeftWidget为例说明,通常在mousePressEvent()中去开启拖动
void LeftWidget::mousePressEvent(QMouseEvent *event)
{if(event->button()==Qt::LeftButton){QString text="xxxxxxx";QMimeData* mimeData=new QMimeData;mimeData->setData("x1",text.toLocal8Bit());QDrag* drag=new QDrag(this);drag->setMimeData(mimeData);qDebug()<<"before drag";drag->exec();qDebug()<<"after drag";}
}
继续使用上一个示例的MainWindow和MyWidget,实现从LeftWidget拖动到MyWidget的效果

如果要实现从拖动按钮到另外一个界面上,使其文字到另外一个窗口
可以通过继承QPushButton然后重写其mousePressEvent,几乎与重写LeftWidget::mousePressEvent一样。
void MyButton::mousePressEvent(QMouseEvent *event)
{if(event->button()==Qt::LeftButton){QString text=this->text();QMimeData* mimeData=new QMimeData;mimeData->setData("x1",text.toLocal8Bit());QDrag* drag=new QDrag(this);drag->setMimeData(mimeData);qDebug()<<"before drag";drag->exec();qDebug()<<"after drag";}return QPushButton::mousePressEvent(event);
}
相关文章:
Qt DragDrop拖动与放置
本文章从属于 Qt实验室-CSDN博客系列 拖放操作包括两个动作:拖动(drag)和放下(drop或称为放置)。 拖动允许 对于要拖出的窗口或控件,要setDragEnabled(true) 对于要拖入的窗口或控件,要setAcceptDrops(true) 下面以一个具体的用例进行说…...
thinkphp8 多级控制器调用
在使用这个目录的时候正常访问时 http://tp.com/index.php/user2.login/index, 这个多级目录时不允许使用的,想要使用就的使用路由 在route/app.php 里面配置:Route::get(user2/login,user2.Login/index); 第一个参数时外部访问参数,第二个是…...
设计测试用例的6种基本原则
设计测试用例的基本原则,对于软件测试非常重要,这些原则有助于设计出高质量、全面、有效的测试用例,从而提高软件测试的效率和准确性,维护软件的质量和稳定。如果在设计用例时没有遵循基本原则,这会影响用例的全面性、…...
java的Exception.getMessage为null
之前捕获异常后调用异常的getMessage写日志,日志写的竟然是null,不可思议。发现要调用异常的getCause().getMessage()才能得到异常信息 刻意把密码改错,让异常直达界面,免得有问题时候只能猜...
EXTI (2)
增强版实验简介 EXTI5和EXTI9共享一个中断源 下面的类似 EXTI0到4各自拥有一个中断源 改变引脚 PA0和PA1改变为PA5 和PA6 EXTI的重映射 之前是把PA0映射到EXTI0 PA1映射到EXTI1上 现在是要把PA5和PA6分别映射到EXTI5和6上 EXTI进行初始化 NVIC初始化 编写中断函数 因为EXTI…...
Django实战项目-学习任务系统-任务完成率统计
接着上期代码内容,继续完善优化系统功能。 本次增加任务完成率统计功能,为更好的了解哪些任务完成率高,哪些任务完成率低。 该功能完成后,学习任务系统1.0版本就基本完成了。 1,编辑urls配置文件: ./mysi…...
安卓调用手机邮箱应用发送邮件
先来看看实现效果: 也不过多介绍了,直接上代码: private void openMail() {Uri uri Uri.parse("mailto:" "");List<ApplicationInfo> applicationInfoList getPackageManager().getInstalledApplications(Packa…...
Vue-Pinia
目录 Pinia状态管理库 使用步骤 1、安装Pinia 2、在vue应用实例中使用pinia 3、在src/stores/token.js中定义stores 4、在组件中使用store axios请求拦截器 代码实现 Pinia状态管理库 Pinia是Vue的专属状态管理库,它允许你跨组件或页面共享状态 一般在登录时…...
C语言,编写程序输出半径为1到15的圆的面积,若面积在30到100之间则予以输出,否则,不予输出
以下是一个使用C语言编写的程序,用于输出半径为1到15的圆的面积,并且如果面积在30到100之间,则输出该圆的半径和面积。 #include <stdio.h> #define PI 3.14159265358979323846int main() {int radius;double area;for (radius 1; ra…...
Ansys Electronics Desktop仿真——HFSS线圈寄生电阻,电感
利用ANSYS Electronics Desktop,可在综合全面、易于使用的设计平台中集成严格的电磁场分析和系统电路仿真。按需求解器技术让您能集成电磁场仿真器和电路及系统级仿真,以探索完整的系统性能。 HFSS(High Frequency Structure Simulator&#…...
对数据库密码使用MD5加密算法加密,并进行登录验证
实现步骤: 修改数据库中明文密码,改为MD5加密后的密文 打开employee表,修改密码 修改Java代码,前端提交的密码进行MD5加密后再跟数据库中密码比对 打开EmployeeServiceImpl.java,修改比对密码 /*** 员工登录** param …...
关于Chrome中F12调试Console输入多行
在chrome 浏览器中使用console调试的时,如果想在console中输入多行代码,需要进行换行。 这时我们可以使用 [ Shift Enter ] 。也叫: 软回车。...
C# 集合用法介绍
在C#中,集合是一种特殊的数据类型,允许我们将多个元素组织在一起。这些元素可以是相同的类型或者可以是不同的类型。C#集合主要包括以下几种类型: List:它是一个有序的元素列表,用户可以添加、删除或查找元素。Dictio…...
linux三次握手、四次挥手
TCP协议是一个安全的、面向连接的、流式传输协议,所谓的面向连接就是三次握手,对于程序猿来说只需要在客户端调用connect()函数,三次握手就自动进行了。先通过下图看一下TCP协议的格式,然后再介绍三次握手的具体流程。 1.tcp协议…...
C# 泛型介绍
C# 中的泛型(Generics)是一种强类型参数化的特性,它允许你编写不具体指定数据类型的代码,而在实际使用时再指定具体的类型。泛型的引入使得代码更加灵活、可重用,并提高了类型安全性。 C#泛型基本用法 以下是一个简单…...
Windows如何正确设置PHP环境变量以在Git Bash中运行命令
1、随便找一个目录,鼠标右键打开git bash here 2、cd的根目录 3、找到php安装目录 4、 在根目录下打开 vim .bash_profile ,添加环境变量,php地址根据自己的本地地址而定 PATH$PATH:/d/phpstudy_pro/Extensions/php/php7.3.4nts 添加后保存…...
[代码实战和详解]VGG16
VGG16 详解 我的github代码实现:vgg16 我们在vgg16神经网络上训练了SIGNS数据集,这是一个分类的数据集,在我的github上有介绍怎么下载数据集以及如何训练。 VGG16是一个卷积神经网络(CNN)架构,它在2014年…...
x3daudio1_7.dll错误:解决方法和丢失原因及作用
x3daudio1_7.dll是Windows操作系统中的一个动态链接库(DLL)文件,主要作用是为DirectX音频提供支持。DirectX是微软推出的一套多媒体应用程序开发接口,广泛应用于游戏、多媒体制作等领域。x3daudio1_7.dll文件包含了许多与三维音频…...
pipeline + node +jenkins+kubernetes部署yarn前端项目
1、编写Dockerfile文件 # Set the base image FROM node:16.10.0# WORKDIR /usr/src/app/ WORKDIR /home/option# Copy files COPY ./ /home/option/# Build arguments LABEL branch${BRANCH} LABEL commit${COMMIT} LABEL date${BUILD_DATE} ARG ENV# Set ENV variables ENV …...
计算机网络中的面向连接与无连接
目录 面向连接和无连接在计算机网络中是如何理解的面向连接和无连接的通信在路由选择上有哪些区别 面向连接和无连接在计算机网络中是如何理解的 在计算机网络中,面向连接和无连接是两种核心的网络通信方式,它们决定了数据包如何传输和接收。 面向连接&…...
MPNet:旋转机械轻量化故障诊断模型详解python代码复现
目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...
【Linux】shell脚本忽略错误继续执行
在 shell 脚本中,可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行,可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令,并忽略错误 rm somefile…...
AtCoder 第409场初级竞赛 A~E题解
A Conflict 【题目链接】 原题链接:A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串,只有在同时为 o 时输出 Yes 并结束程序,否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...
oracle与MySQL数据库之间数据同步的技术要点
Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异,它们的数据同步要求既要保持数据的准确性和一致性,又要处理好性能问题。以下是一些主要的技术要点: 数据结构差异 数据类型差异ÿ…...
相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...
Rust 异步编程
Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...
OPENCV形态学基础之二腐蚀
一.腐蚀的原理 (图1) 数学表达式:dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一,腐蚀跟膨胀属于反向操作,膨胀是把图像图像变大,而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...
Angular微前端架构:Module Federation + ngx-build-plus (Webpack)
以下是一个完整的 Angular 微前端示例,其中使用的是 Module Federation 和 npx-build-plus 实现了主应用(Shell)与子应用(Remote)的集成。 🛠️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...
【生成模型】视频生成论文调研
工作清单 上游应用方向:控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...
站群服务器的应用场景都有哪些?
站群服务器主要是为了多个网站的托管和管理所设计的,可以通过集中管理和高效资源的分配,来支持多个独立的网站同时运行,让每一个网站都可以分配到独立的IP地址,避免出现IP关联的风险,用户还可以通过控制面板进行管理功…...
