Qt中自定义控件拖拽,QT实现拖拽功能--小白友好版-程序员宅基地

技术标签: c++  qt  开发语言  

目录

创作背景

开发环境

 运行效果

实现原理

        1.参考文档       

       2.主要原理 

实现过程

        1.首先是重写QLabel

        2.第二步是使用自己写的Label类

总结


创作背景

        写这篇文章主要有一下几点原因。第一个呢就是小白学习qt,准备实现拖拽效果但是不会写。再一个就是在网上找到的教程都是参差不齐,没找到特别详细的,对小白友好的教程。所以在研究透彻之后供大家参考。有不正确的地方还请大家指正。

开发环境

        QT5.12.2 + win11 +minggw73

 运行效果

实现原理

        1.参考文档       

Qt拖拽,官方文档http://xn--gqq717c/

      MimaData文档https://doc.qt.io/archives/qt-5.5/qmimedata.html#setImageData

       2.主要原理 

        以QLabel为例,当鼠标按住QLabel会触发mousePressEvent(QMouseEvent *a_event)事件

,当你按住这个QLabel拖动一段距离时,会触发mouseMoveEvent(QMouseEvent *a_event)

事件。当鼠标拖动一个QLabel进入另外一个QLabel【也可以是它自己】时,会触发dragEnterEvent(QDragEnterEvent *a_event)事件,当鼠标拖动一个QLabel进入另外一个QLabel【也可以是它自己】并且松开鼠标时会触发dropEvent(QDropEvent *a_event)。

        但是,QLabel封装的时候并没有在这几个事件触发时添加处理逻辑。所以需要创建一个QLabel的子类,来重写这些事件函数,并且添加处理逻辑。

        好了,到此为止。需要用到的主要事件和在哪里触发就说完了。

实现过程

        1.首先是重写QLabel

                .h头文件

                

#ifndef DROPQLABEL_H
#define DROPQLABEL_H
#include<QLabel>
#include<QDragEnterEvent>
#include<QMimeData>
#include<QDrag>
#include<QDebug>
#include<QApplication>

class DropQLabel : public QLabel//公开继承QLabel
{
    Q_OBJECT
public:
    
    DropQLabel(QWidget *parent = nullptr);
    ~DropQLabel();
    //重写鼠标放下时事件处理函数
    void dropEvent(QDropEvent* a_event);
    //重写鼠标拖入时事件处理函数
    void dragEnterEvent(QDragEnterEvent* a_event);
    //重写鼠标按住时事件处理函数
    void mousePressEvent(QMouseEvent *a_event);
    //重写鼠标移动时事件处理函数
    void mouseMoveEvent(QMouseEvent *a_event);

};

#endif // DROPQLABEL_H

        .cpp文件

#include "dropqlabel.h"


DropQLabel::DropQLabel(QWidget *parent):QLabel(parent)//调用父类的构造函数
{
    //构造函数中可以没有内容,但是必须实现
}

DropQLabel::~DropQLabel()
{
    //析构函数也是,可以没有内容但是必须实现
}
//鼠标放下的事件
void DropQLabel::dropEvent(QDropEvent *a_event)
{
    QString a="我接受到拖拽内容了,内容是:"+a_event->mimeData()->text();//解析mamiData中携带的信息
    qDebug()<<a;
}
//鼠标拖入的事件
void DropQLabel::dragEnterEvent(QDragEnterEvent *a_event)
{
        // 如果拖动的事件中有Text,则允许drop。如果没有Text则不允许放下
       if (a_event->mimeData()->hasText())
       {
           // 如果未调用,则无法drop
           a_event->acceptProposedAction();
       }
}

void DropQLabel::mousePressEvent(QMouseEvent *a_event)
{
    
}

void DropQLabel::mouseMoveEvent(QMouseEvent *a_event)
{
    if (a_event->buttons() & Qt::LeftButton)//判断是否时鼠标的事件,且为左键则执行
        {
            QApplication::startDragDistance())
            //Qt中拖拽时需要生成一个Drag对象,才能实现拖拽
            这些事件声明也可以放在mousePressEvent(QMouseEvent *a_event)函数中
            QDrag *drag = new QDrag(this);
            //拖拽时也必须声明一个MimeData可以用来传递信息,如果不需要传递信息也要声明并且调用drag的setMimeData()函数,否则会报错。
            QMimeData *mimeData = new QMimeData;
            QString labelText=this->text();
            QString a="我开始被拖拽了,发送的拖拽内容是:"+this->text();
            this->setText(a);
            //可以调用mimeData的各种方法设置想要mimeData传递的信息
            mimeData->setText(labelText);
            drag->setMimeData(mimeData);
            drag->exec();//最后调用exec()即可
        }

}

QLabel的重写工作完成之后,也就完成了大半。

        2.第二步是使用自己写的Label类

                在QtCreator的ui编辑器中拖入一个QLabel右键单击,在快捷菜单中选择“提升为”选项。

在弹出的对话框中输入类名,点击添加

添加成功后选中类,点击对话框底部的提升按钮。

 看到下图处,类名改变则表示提升成功。

 最后在mainWindow的cpp代码构造函数中允许放下的动作setAcceptDrops(true);

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    DropQLabel* aa=this->findChild<DropQLabel *>("bbb");
    DropQLabel* bb=this->findChild<DropQLabel *>("aaa");
    //设置允许放下动作
    bb->setAcceptDrops(true);
    //再设置父UI框架为允许放下,否则会失败。
    this->setAcceptDrops(true);

}


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

 至此,所有工作已经完成。

总结

        大致步骤就是:重写QLabel=>使用自己写的控件=>在主窗口中设置允许鼠标放下动作。

        然后就是:

        Qt开发任重道远,加油吧!!

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

智能推荐

网络分流器|高速骨干网流量采集与分流实现-程序员宅基地

文章浏览阅读202次。网络分流器|高速骨干网流量采集与分流实现方案1 流量采集|网络分流器所谓流量采集,就是将网络流量通过物理层、数据链路层的信号解析和解帧,实现IP原始报文的获取。骨干网流量采集系统是一种对骨干网进行流量获取并分析的系统,主要应用于政府网络管理、运行商广告推送、运行商计费取证服务、运行商信令监控服务、园区网审计、公安网监、大数据分析等领域。2 高速网络流量采集系统|网络分..._流上报 分流器 doc

ESP32 (UART 接收发送)-串口之接收发送通讯(4)_esp32接收发送16进制指令-程序员宅基地

文章浏览阅读9.7k次,点赞8次,收藏54次。提示:本博客作为学习笔记,有错误的地方希望指正文章目录一、ESP32串口介绍二、硬件设计三、实现代码四、串口实验演示结果五、ESP32串口函数API5.1、uart_types.h文件中的内容的API5.2、在uart.h文件中的内容的API一、ESP32串口介绍  UART 是一种以字符为导向的通用数据链,可以实现设备间的通信。异步传输的意思是不需要在发送数据上添加时钟信息。这也要求发送端和接收端的速率、停止位、奇偶校验位等都要相同,通信才能成功。  一个典型的 UART 帧开始于一个起始位,紧接_esp32接收发送16进制指令

第4章 学习Shader所需的数学基础(下)(坐标空间及其变换)_扩展到齐次坐标空间-程序员宅基地

文章浏览阅读580次。版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 ..._扩展到齐次坐标空间

插入排序、冒泡排序、选择排序、快速排序、归并排序、堆排序-程序员宅基地

文章浏览阅读345次。插入排序、冒泡排序、选择排序、快速排序

【Linux】Bonding配置,管理-程序员宅基地

文章浏览阅读217次。1 通过Ifenslave手动配置Bonding该方法适用于某些发行包,它们的网络初始化脚本(sysconfig或initscripts包)没有bonding相关的知识。SuSE Linux Enterprise Server 版本8就是这样的一个发行包。对于这些系统一般的方法是,把bonding模块的参数放进/etc/modules.conf或..._echo "all" > /sys/class/net/bond0/bonding/arp_validate echo "100" > /sys

随便推点

程序员面试被要求徒手写代码?你与顶级程序员差别就在这!_自从自己入职稳定以后,就一直在整理自己这一段时间自己的经历,想要写下来。今天是-程序员宅基地

文章浏览阅读346次。在面试中,你被要手写代码,原本自信心爆棚的你突然间提笔忘字。在一张纸上反复涂涂画画,最后勉强的写出了一个功能。结果却漏洞百出。面试过程相当不顺利,丢下笔,敷衍的结束了这场面试,回去对周围的朋友苦涩地说:这都什么时代了,还要求手写代码?这家公司落后了。然而,这就是你与顶级程序员最根本的差距。那么顶级程序员们手写代码都特别厉害吗?随便一动笔就是行云流水,一泻千里?不不不!也许,他们根本就没手写过代..._自从自己入职稳定以后,就一直在整理自己这一段时间自己的经历,想要写下来。今天是

【c++】rand()随机函数的应用(二)——舒尔特方格数字的生成_山东大学c++舒尔特方格代码-程序员宅基地

文章浏览阅读800次。本例提出了一种新的方法实现不同维数舒尔特方格的生成方法,需要用到rand()、srand()函数,在算法上采用动态取模方法。_山东大学c++舒尔特方格代码

android输入法好用,安卓手机输入法哪个最好用?-程序员宅基地

文章浏览阅读2.5k次。纵观目前的安卓手机输入法,已经获得大多数用户认可的有以下四种:搜狗输入法、百度输入法、QQ输入法,以及讯飞语音输入法。但是这四种安卓手机输入法哪个最好用?谁的联想最完美,稳定性和兼容性最强?今天,凌少就通过四种输入法的详细对比介绍,来告诉大家,到底安卓手机输入法哪个最好用。评测手机:HTC HD2手机系统:Andriod 2.2评测对象:搜狗输入法、百度输入法、QQ输入法,以及讯飞口讯语音输入法手..._安卓手机好用的输入法

Kibana:创建你的第一个仪表板_kinaba仪表盘-程序员宅基地

文章浏览阅读2.8k次,点赞4次,收藏4次。了解从你自己的数据创建仪表板的最常用方法。本教程将从分析师查看网站日志的角度使用示例数据,但这种类型的仪表板适用于任何类型的数据。完成后,你将全面了解示例 Web 日志数据。在本次的展示中,我将使用最新的 Elastic Stack 8.7.1 来进行展示。_kinaba仪表盘

layui table表格带图片,图片显示不全问题_layui表格图片显示不全-程序员宅基地

文章浏览阅读9.8k次,点赞10次,收藏30次。这个平时没有注意过,今天有人问到,就记录一下吧layui的表格使用非常简单,layui文档中已经非常详细,下面直接上代码了1.jsp代码 <div class="demoTable"> <button class="layui-btn" data-type="publish">发布Banner</button> </..._layui表格图片显示不全

Android音视频开发 -> fdk-aac解码eld-aac为pcm_android aac音频解码-程序员宅基地

文章浏览阅读1.1k次。大体实例fdk-aac 解码初始化fdk-aac 开始解码公共变量//解码器对象实例HANDLE_AACDECODER aacDecoder;fdk-aac解码初始化int FdkAacDecode::fdkAacDecodeInit(JNIEnv *env) { //Java方法初始化 aacDecodeClass = env->FindClass("com/zkzj/aaclib/AacUtil"); aacDecodeId = env->GetM_android aac音频解码

推荐文章

热门文章

相关标签