Qt 实现拖放内容 drag - drop 【简单明了】_ShenMingYi_的博客-程序员资料_qt的drag和drop

技术标签: Qt  

前言:

看几天看了 Qt 实现跨‘窗口’,‘程序’ 拖拽 文件,信息,图片之类
感觉看完他们写的文章 ,还是不太明白 自己看了看 试了试
写这篇文章巩固一下

本文说的比较详细简单

我下面录制的 gif 因为拖拽时 的图标不会被录制进去 观看会受到极大的影响

在这里插入图片描述

下面是我用手机照的照片

移动过程中 …
在这里插入图片描述
在这里插入图片描述

我们仔细的看这个过程

1.当我们鼠标 点击 send widget 时候 会触发 mousePressEvent
2. 当我们按压鼠标 移动的过程中 会触发 mouseMoveEvent
3. 当我们拖拽鼠标进入窗口 recv widget 会触发 dragEnterEvent
4. 当我们松开鼠标 会触发 dropEvent

sendWidget.h


#include <QMainWindow>

class QLineEdit;
class recvWidget;



class MainWindow : public QMainWindow
{
    
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();


protected:
    void mousePressEvent(QMouseEvent *event) override;
    void mouseMoveEvent(QMouseEvent *event) override;

private:
    QPointF m_pressPoint;
    QLineEdit *m_lineEdit;
    bool m_isMoving;

    recvWidget *m_recvWidget;
};

sendWidget.cpp

#include "recvwidget.h"

#include <QMouseEvent>
#include <QLineEdit>
#include <QApplication>
#include <QDrag>
#include <QMimeData>
#include <QDebug>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent)
{
    
    this->resize(300,200);
    this->setWindowTitle("send widget");

    m_lineEdit = new QLineEdit(this);
    m_recvWidget = new recvWidget();
    m_recvWidget->show();

}

MainWindow::~MainWindow()
{
    
    delete m_lineEdit;
}

void MainWindow::mousePressEvent(QMouseEvent *event)
{
    
    qDebug()<<"[mainWindow]:mousePress";
    m_pressPoint = event->screenPos();
    m_isMoving = false;
}

void MainWindow::mouseMoveEvent(QMouseEvent *event)
{
    
    if(QLineF(event->screenPos(),m_pressPoint).length() < QApplication::startDragDistance() || m_isMoving)
        return;
    qDebug()<<"[mainWindow]:mouseMove";

    m_isMoving = true;

    QDrag *drag = new QDrag(this);
    QMimeData *mimeData = new QMimeData();

    QPixmap pixmap("C://Users//Administrator//Desktop//icon.jpg");
    drag->setPixmap(pixmap);
    drag->setHotSpot(QPoint(20,30));

    drag->setMimeData(mimeData);

    QByteArray byteArray(m_lineEdit->text().toUtf8());

    mimeData->setData("text",byteArray);

    drag->exec();

}

咱们 sendWidget 就说1个函数 怎么把数据拖拽过去的

在这里插入图片描述

首先 拖拽由两部分组成

  1. 按压鼠标
  2. 移动鼠标

按压鼠标时 我们获取鼠标在整个屏幕的位置

if(QLineF(event->screenPos(),m_pressPoint).length() < QApplication::startDragDistance() || m_isMoving)
    return;

开始移动时候 我们判断一下 我们按压的位置 和 现在移动到的位置 他们之间的距离
是不是大于 dragDistance 的距离 默认是10像素

在这里插入图片描述

距离达不到就不算拖拽

当达到拖拽条件以后

在这里插入图片描述

有的可能不懂 QMimeData 了

在这里插入图片描述

译文:
QMimeData类为记录其MIME类型信息的数据提供了一个容器。
QMimeData用于描述可以存储在剪贴板中的信息,并通过拖放机制进行传输。QMimeData对象将它们持有的数据与相应的MIME类型相关联,以确保信息可以在应用程序之间安全地传输,并在同一个应用程序中进行复制。
QMimeData对象通常使用新的并提供给QDrag或QClipboard对象来创建。这是为了使Qt能够管理它们所使用的内存。

单个QMimeData对象可以同时使用几种不同的格式存储相同的数据。函数的作用是:按优先顺序返回可用格式的列表。data()函数返回与MIME类型关联的原始数据,而setData()允许您设置MIME类型的数据。
对于最常见的MIME类型,QMimeData提供了方便的函数来访问数据:

通俗讲 就是把你想发的数据 必须由 QMimeData 包装一下 才能被另一个收到

在这里插入图片描述

我设置了一个 拖拽时的 鼠标的icon 就是他在这里插入图片描述

setHotSpot 就是设置 让不接收拖拽时的 叉号 的位置

在这里插入图片描述
下面就是把我们的 lineEdit 的数据 用 QbyteArray 存储一下 放到 QMimeData

前面的 “text” 非常重要 是mimetype
就相当于 是密码
接收数据的一方想要 拆开 QMimeData 的数据 必须要 输对 mimetype

mimeData->setData("text",byteArray);

ok 这样一个发送方的 拖拽数据就准备好了

下面看接收方的

recvWidget.h

#include <QWidget>
class QLabel;
class recvWidget : public QWidget
{
    
    Q_OBJECT
public:
    explicit recvWidget(QWidget *parent = nullptr);
protected:
    void dropEvent(QDropEvent *event) override;
    void dragEnterEvent(QDragEnterEvent *event)override;

private:
    QLabel* m_label;
};
#include "recvwidget.h"
#include <QDropEvent>
#include <QMimeData>
#include <QDebug>
#include <QLabel>


recvWidget::recvWidget(QWidget *parent) : QWidget(parent)
{
    
    this->resize(300,200);
    this->setWindowTitle("recv widget");

    m_label = new QLabel(this);
    m_label->setText("等待接收拖拽数据......");

    QFont font;
    font.setPixelSize(16);
    m_label->setFont(font);

    this->setAcceptDrops(true);
}

void recvWidget::dragEnterEvent(QDragEnterEvent *event)
{
    
    if(event->mimeData()->hasFormat("text"))
    {
    
        event->accept();
        qDebug()<<"[recvWidget]: dragEnterEvent accept";
    }
    else
        event->ignore();
}

void recvWidget::dropEvent(QDropEvent *event)
{
    
    qDebug()<<"[recvWidget]:dropEvent drop";

    if(event->mimeData()->hasFormat("text"))
    {
    
        QByteArray byteArray = event->mimeData()->data("text");
        m_label->setText("recv:"+QString(byteArray));

        event->setDropAction(Qt::MoveAction);
        event->accept();
    }
    else
        event->ignore();

}

首先 注意 如果要使窗口 能接收拖拽事件 必须开启接收drop

    this->setAcceptDrops(true);

还是只看 这俩函数

在这里插入图片描述

dragEnterEvent 事件是 鼠标进入到本窗口

只要你按着鼠标移动到 窗口里面 不用松手
就会进入 dragEnterEvent 事件

前提是你要 accept

在这里插入图片描述

event->mimeData()->hasFormat("text")

就是判断这个 拖拽来的东西 是不是我们想要的

就相当于快递员给你送快递 你看到快递 看上面单号是不是你的就行 不需要拆开看里面的东西

在这里插入图片描述
dropEvent 是松鼠标以后 进入的事件
把数据拆开 显示就ok 了

这是个很基础 简单 便于我们理解

后面咱们来看一下 Qt 官方demo 拼图的 源码
Qt 实现拼图【官方demo 源码超详细解读】

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_42837024/article/details/105557761

智能推荐

CentOS7配置vsftpd3.0.2_weixin_30686845的博客-程序员资料

1、安装和查看  yum install -y vsftpd    rpm -ql vsftpd ----查看所有和vsftpd相关的文件或文件夹    vsftpd -v ----查看vsftpd版本2、启动vsftpd,设置vsftpd开机启动3、设置selinux为disabled4、设置firewall防火墙  #firewall-cm...

将Hexo自动部署到Github Pages_Oscar_e的博客-程序员资料_hexo发布到github pages

Hexo建站比较简单,并提供了多种模板,方便快速开发个人博客。在使用过程中,唯一让我感到麻烦的地方,就是每次修改完内容之后,都得重新编译,然后将编译完的静态文件重新上传到github仓库(或者自己的服务器)再搜索过程中,发现使用Hexo的小伙伴都碰到过这种问题,并且已有合适的解决方案。以下记录本站自动部署过程。 前期所需:Hexo 项目Github 账户Travis 账户(与GitHub关联的)正文1. 建立Hexo项目按照Hexo的教程,依次运行以下命令,建立新项目blog

Android开发者网站博客导航_野猿新一的博客-程序员资料

Android 开发者网址导航常用网站大厂博客大牛博客程序员资料公众号社区论坛GitHub求职招聘面试指南在线学习应用商店常用工具常用网站Google Developers Android Developers GitHub Stack Overflow 干货集中营大厂博客美团技术团队 知乎技术专栏大牛博客胡凯 尼古...

netstat_kevin_darkelf的博客-程序员资料

netstat 常用操作:[[email protected] ~]# netstat -nlpnetstat命令各个参数说明如下:   -t : 指明显示TCP端口   -u : 指明显示UDP端口   -l : 仅显示监听套接字(所谓套接字就是使应用程序能够读写与收发通讯协议(protocol)与资料的程序)   -p : 显示进程标识符和程序名称,每一个套接字/端口都属于一个程序。   -

matlab批量修改文件名为顺序数字_yudou2019的博客-程序员资料_文件名怎么重命名为顺序数字 matlab

这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入欢迎使用Ma...

吃鸡显示服务器脱机,steam服务器脱机_你就应该的博客-程序员资料

[详情]Ben hero is back and he has for you another new and fun adventure game. Because you love all of Ben hero games, our team is offering them as soon as they are found, so that you can spend time play...

随便推点

小程序修改原生标题栏返回键的方法_林恒smileZAZ的博客-程序员资料

在开发的过程中,我遇到过一个需求,需要将4到5个页面合为一个,在页面里制作切换和返回方法,我想使用原生的标题,这个时候就面临着一个问题,返回方法怎么办,原生标题的返回方法无法监听到,那么将制作返回功能。解决方法:在小程序的生命周期中,有这么一个周期 /** * 生命周期函数--监听页面卸载 */ onUnload: function () { },这里...

关联式容器——hash_set和hash_multiset_哎呦,帅小伙哦的博客-程序员资料_std::multiset与hash_set

hash_set STL set多半以RB-tree为底层实现。SGI则是在STL标准规格之外又提供了一个所谓的hash_set,以hash_table为底层实现机制。由于hash_set所提供的操作接口,hashtable都提供了,所以几乎所有hash_set操作行为,都只是调用hashtable的操作而已。但是需要注意的是红黑树有自动排序功能而哈希表没有,所反应出来的结果就是,se...

深度学习新的采样方式和损失函数--论文笔记_LittleStudent12的博客-程序员资料_采样和损失函数之间的关系

深度学习新的采样方式和损失函数--论文笔记论文《Sampling matters in deep embedding learning》论文地址:https://arxiv.org/pdf/1706.07567.pdf 该论文为2017年6月上传至arxiv。主要研究的是深度嵌入学习(deep embedding learning)中的采样问题和损失函数的问题。作者分析了contrasti...

数据结构与算法——算法_算法和数据结构_小田『开心馆』的博客-程序员资料

算法是对特定问题求解的步骤的一种具体描述,算法是指令的有有限序列,其中每一条指令表示一个或是多个操作,用于解决某个问题。本文主要讲解了数据结构与算法——算法的基本概念,知识点详细。...

D3D12渲染技术之网格地形_海洋_的博客-程序员资料_网格地形

本篇博客我们将展示一个案例, 该案例实现在程序上构造三角形网格,通过偏移顶点高度以创建地形。 此外,使用另一个三角形网格来表示水,并设置顶点高度的动画以创建波浪。 此案例还切换到使用根描述符作为常量缓冲区,这允许我们放弃对CBV的描述符堆的支持。 我们用函数y = f(x,z)实现表面, 通过在xz平面构建网格来近似表面,其中每个四边形由两个三角形构成,然后将函数应用于每个网格点; 见下图:...

数据结构与算法期末复习——知识点+题库_软件手的博客-程序员资料

大学生 数据结构期末复习——知识点+题库四川轻化工

推荐文章

热门文章

相关标签