Qt Drag and Drop 实现拖拽控件效果

Qt编写可拖拽的自定义控件 qt实现的可自定义拖拽控件 阅读详情

效果预览

拖拽实现效果
代码链接:https://download.youkuaiyun.com/download/ASCE_Python/12146370

本例子实现拖拽一个label效果,主要是四个函数的定义实现,Drag前要记录原来的数据存入到MimeData中,比如这里的图片和控件初始位置,Drop时要读出原来存储的数据并根据该数据还原为最初的模样

在头文件中声明事件操作函数,MainWindow.h中如下:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;

protected:
    void mousePressEvent(QMouseEvent *event);
    void dragEnterEvent(QDragEnterEvent *event);
    void dragMoveEvent(QDragMoveEvent *event);
    void dropEvent(QDropEvent *event);
};
#endif // MAINWINDOW_H

在cpp中重写事件函数的实现部分,MainWindow.cpp如下:

#include "MainWindow.h"
#include "ui_MainWindow.h"
//增加相关头文件
#include <QLabel>
#include <QMouseEvent>
#include <QDragEnterEvent>
#include <QDragMoveEvent>
#include <QDropEvent>
#include <QPainter>
#include <QUrl>
#include <QFile>
#include <QTextStream>
#include <QMimeData>
#include <QDrag>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    setAcceptDrops(true);       //默认控件不支持拖拽,需在构造函数中设置接受拖拽事件
    QLabel *label = new QLabel(this);  //新建一个label并增加了名称叫connect的图片,label尺寸与图片大小相同
    QPixmap pix("../DragEvent/connect.ico");
    label->setPixmap(pix);
    label->resize(pix.size());
    label->move(100,100);
    label->setAttribute(Qt::WA_DeleteOnClose);

}

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

void MainWindow::mousePressEvent(QMouseEvent *event)   //按下事件实现
{
    //1 获取当前鼠标指针所在处的部件的指针,强制转换为QLabel类型的指针
    QLabel *child = static_cast<QLabel*>(childAt(event->pos()));
    if(!child->inherits("QLabel"))
    {
        return;
    }
    QPixmap pixmap = *child->pixmap();

    //2 自定义Mime类型数据,存储图片数据和位置信息
    QByteArray itemData;
    QDataStream dataStream(&itemData,QIODevice::WriteOnly);
    dataStream<<pixmap<<QPoint(event->pos()-child->pos());

    //3 将数据字节数组存入MimeData中,这里相当于setData作用类似<key,value>
    QMimeData *mimeData = new QMimeData;
    mimeData->setData("myimage/png",itemData);

    //4 为了移动数据必须创建Drag类对象,然后为其添加QMimeData数据
    QDrag *drag = new QDrag(this);
    drag->setMimeData(mimeData);
    drag->setPixmap(pixmap);
    drag->setHotSpot(event->pos()-child->pos());

    //5 在移动图片过程中为原来图片添加了一层阴影
    QPixmap tempPixmap = pixmap;
    QPainter painter;
    painter.begin(&tempPixmap);
    painter.fillRect(pixmap.rect(),QColor(127,127,127,127));
    painter.end();
    child->setPixmap(tempPixmap);

    //6 执行拖动操作,默认设置支持复制操作
    if(drag->exec(Qt::CopyAction|Qt::MoveAction,Qt::CopyAction) == Qt::MoveAction)
    {
        child->close();
    }
    else
    {
        child->show();
        child->setPixmap(pixmap);
    }
}

void MainWindow::dragEnterEvent(QDragEnterEvent *event)  //进入拖拽
{
    if(event->mimeData()->hasFormat("myimage/png"))
    {
        event->setDropAction(Qt::MoveAction); //a.移动操作
        event->accept();
    }
    else
    {
        event->ignore();
    }
}

void MainWindow::dragMoveEvent(QDragMoveEvent *event)  //移动事件
{
    if(event->mimeData()->hasFormat("myimage/png"))
    {
        event->setDropAction(Qt::MoveAction); //b.移动操作
        event->accept();
    }
    else
    {
        event->ignore();
    }
}

void MainWindow::dropEvent(QDropEvent *event)     //放下事件
{
    if(event->mimeData()->hasFormat("myimage/png"))
    {
        QByteArray itemData = event->mimeData()->data("myimage/png");
        QDataStream dataStream(&itemData,QIODevice::ReadOnly);
        QPixmap pixmap;
        QPoint offset;
        dataStream>>pixmap>>offset;
        QLabel *newLabel = new QLabel(this);
        newLabel->setPixmap(pixmap);
        newLabel->resize(pixmap.size());
        newLabel->move(event->pos()-offset);
        newLabel->show();
        newLabel->setAttribute(Qt::WA_DeleteOnClose);
        event->setDropAction(Qt::MoveAction); //c.移动操作
        event->accept();
    }
    else
    {
        event->ignore();
    }
}

Qt Drag&Drop拖动与放置 本文章从属于系列拖放操作包括两个动作:拖动(drag)和放下(drop或称为放置)。 阅读详情

相关推荐

Qt开源控件库全解析:从QCustomPlot实战到高效开发心法

在桌面应用开发中,UI组件库是提升开发效率和界面质量的核心技术。其原理在于通过封装复杂的绘图、事件处理和布局逻辑,为开发者提供可复用的高级控件,从而避免重复造轮子。这类库的技术价值在于显著降低实现复杂功能(如数据可视化、专业图表、现代化交互)的难度,同时确保视觉风格的一致性和跨平台兼容性。在实际应用场景中,开发者常面临原生控件功能不足、界面美观度欠佳或特定领域(如工业控制、科学计算)需求难以满足的挑战。本文聚焦Qt生态,深入探讨如何利用QCustomPlot等开源控件库解决这些痛点,涵盖从选型评估、实战集成

weixin_34082695的博客 455

使用QT进行简单的控件拖拽

通过QT实现对控件的拖拽移动操作

weixin_43699794的博客 2810

Qt5 GUI编程实战:从自定义控件到多线程优化的核心技巧

在C++桌面应用开发中,图形用户界面(GUI)的实现与优化是提升用户体验的关键环节。Qt框架以其强大的跨平台能力和丰富的组件库,成为该领域的主流选择。其核心原理在于信号与槽的通信机制、模型/视图的分离设计以及基于事件的渲染体系,这些特性共同支撑了高效、可维护的界面开发。从技术价值看,掌握Qt不仅能快速构建标准界面,更能通过自定义控件、样式表(QSS)和高级绘图(QPainter)实现独特的视觉效果,满足专业软件的需求。在实际应用场景中,开发者常面临界面卡顿、内存管理以及复杂交互(如拖放操作、Web内容集成)

germmy-神一样的开发 429

Qt中自定义控件拖拽,QT实现拖拽功能--小白友好版

大致步骤就是重写QLabel=>使用自己写的控件=>在主窗口中设置允许鼠标放下动作。然后就是Qt开发任重道远,加油吧!!httpshttpst=M666httpst=M666httpshttpshttpshttpsQt拖拽,官方文档httpsMimaData文档https。

qq_43710667的博客 1万+

Qt Tab Widget 进阶技巧:自定义标签样式与交互(圆角/三角形/位置调整)

本文深入探讨了Qt Tab Widget的高级定制技巧,包括通过QSS样式表实现圆角/三角形标签样式、灵活调整标签位置以及增强动态交互效果。通过实际代码示例展示了如何提升桌面应用的视觉吸引力和用户体验,特别适合需要深度定制UI的Qt开发者。

weixin_27027459的博客 248

Qt中的移动控件

在mouseMoveEvent中,如果鼠标按下左键并移动,就根据鼠标当前位置以及偏移量计算出控件应该移动到的新位置,并调用QWidget类的move()函数来实现控件的移动效果。在Qt中,要实现控件的移动,我们可以使用QWidget类的move()函数。通过运行程序,我们可以看到当鼠标按下并移动时,控件会跟随鼠标的移动而发生位置变化,从而实现了控件的移动效果。总之,Qt提供了简单易用的控件移动功能,通过使用move()函数以及鼠标事件处理函数,我们可以很容易地实现控件的移动效果。

ScriptCharm的博客 1477

Qt自定义图形实现拖拽效果

在这里自定义图形是通过QPaintEvent事件绘画的图形,也可以通过自定义控件的方式添加到qt中。 首先定义类来自定义图形,这里通过paintEvent事件来实现(主要就是绘画一个图形) void QEventView::paintEvent(QPaintEvent *event) { resize(115+m_iLen,36); QPainter painter(this...

Tjmies的博客 5251

QT实现自定义控件拖拽(附完整源码)

QT实现自定义控件拖拽(附完整源码)

希望我的博客,能帮上你解决学习中工作中所遇到的问题 1539

Qt Drag and Drop 学习笔记

 QtDrag and Drop 学习笔记  Drag&Drop的直观效果可以从QtDesigner中的控件拖动中看出来。Drag&Drop可以实现同一个控件或者两个控件之间传递数据。其传递的数据通过QMimeData进行传递,默认的MineType包括Text及image,也可以自行定义类型。 具体做法 在Qt中实现的时候是通过Widget的dragEnt

jingwenlai_scut 3501

Qt QToolButton 拖拽排序实现:事件重写与布局干预

QToolButton 作为轻量级工具按钮,原生不支持拖拽排序,其本质是缺乏对 Qt 拖放事件链(dragEnterEvent/dropEvent)和布局管理(QLayout::insertWidget)的参与能力。要实现稳定拖放,需从鼠标事件拦截、MIME 数据构造、坐标到布局索引的映射转换等底层原理入手,解决 drag 启动阈值判断、插入点动态计算、父子控件事件冲突等关键技术难点。该方案具备零侵入式集成特性,兼容 QAction 绑定与图标资源体系,广泛适用于 Qt 工具栏定制、用户可配置 UI 面板及

weixin_28366475的博客 313

qt实现qgaphicsitem的拖动连线等操作

支持qgraphicitem在scene中拖动和缩放,支持qgraphicsitem间的连线操作,代码可扩展。

QtQuick-TreeView如何拖拽或移动item到其他item

由于qml中的TreeView属于QtQuick1.x,目前也不再进行feature上的扩展,相关的资料也不多,导致想在上面实现一些常见的操作也变得困难,比如本次想在TreeView实现从移动item到其他item上。 我们之前的文章在qml-TreeView自定义模型里的数据讲解了如何在TreeView传递自定义数据类型,本次文章仍然在这个基础上实现。 import QtQuick 2.7 im...

hai7song的专栏 1227

H3C设备VRF配置实战:5步搞定多业务网络隔离(附排错技巧)

本文详细介绍了在H3C设备上配置VRF(虚拟路由转发)实现多业务网络隔离的实战方法。通过五步配置流程,从创建VPN-instance、绑定接口到配置独立路由表,帮助网络工程师在单台设备上构建逻辑隔离的企业级网络,并分享了高级路由配置与常见排错技巧。

gold8的专栏 936

VC实现文件管理器拖拽(Drag-and-Drop)

VC实现文件管理器拖拽(Drag-and-Drop) 在日常的程序中,为了操作的方便,经常需要使用鼠标拖拽的方式把文件管理器中的文件拖拽到我们自己写的程序中,以下就简单介绍以下实现该操作的方法。 其实文件管理器的拖拽方式实现起来很简单,主要通过几个函数来实现,消息WM_DROPFILES的响应函数OnDropFiles,还有三个API函数:DragQueryFile,DragQuery

2007

FANUC机器人RSR与PNS功能深度解析及实战应用指南

本文深度解析了FANUC机器人RSR(远程程序启动)与PNS(程序号选择)两大核心功能。文章详细阐述了RSR的队列执行机制与PNS的二进制编码原理,提供了从硬件连接到参数配置的完整实战指南,并分享了混合使用策略与常见故障排除方法,旨在帮助工程师实现高效、稳定的生产线自动化程序调度。

neovim7hacker的博客 308

比Synergy更轻量!Barrier鼠标共享工具实测:5分钟实现Win/Mac/Linux三设备无缝切换

本文实测了开源免费的Barrier鼠标共享工具,详细指导用户如何在5分钟内于Windows、macOS和Linux三台设备间实现一套键鼠的无缝切换。文章对比了其与Synergy的优势,提供了分平台安装、核心服务端-客户端配置、防火墙设置等完整教程,并分享了解决连接问题的关键技巧,是提升多设备办公效率的实用指南。

weixin_29304021的博客 595

Qt GUI 模块

在core模块之上,就是最为重要的GUI模块了。Qt4中只有QtGui模块,UI相关的功能都封装在一起。Qt5中拆分为GUI、Widget两个模块。GUI模块提供桌面系统集成,事件处理,OpenGL/Vulkan,基础图像,字体等功能。通过链接1 可知,GUI模块的class 是相当少的。但是,它们却是Qt 界面技术的核心。我们甚至可以不使用Qt Widget 模块,也能做出来符合设计的UI功...

know yourself 2787

SBP依赖计算中的蝴蝶效应:一个Prefab修改如何触发全量重建?

本文深入探讨了Unity中SBP(Scriptable Build Pipeline)依赖计算的蝴蝶效应,解析了Prefab修改如何触发全量重建的机制。通过分析Asset与Object的层级关系、依赖计算的三种维度及CacheEntry系统,揭示了全量重建的根本原因,并提供了依赖可视化工具开发、优化策略与最佳实践,帮助开发者提升构建效率。

weixin_29015051的博客 444

Qt: QDropEvent拖拽事件,拖拽打开文件

Qt: QDropEvent拖拽事件,拖拽打开文件

好儿郎~志在四方 1万+

单片机入门说明书:从本质到架构,一文看透MCU核心原理

其实你每天用的洗衣机、刷的智能门锁、开的汽车里,都藏着它的身影。相当于工厂里的“运输轨道”,CPU算出的结果通过总线送到RAM存储,ROM里的程序通过总线传给CPU执行,外设的信号通过总线交给CPU处理,整个过程每秒能重复上百万次,确保各模块协同高效。高端单片机(比如STM32F4系列)还会配备DMA(直接存储器访问)单元,相当于“专用传送带”——不需要CPU干预,就能直接让外设和RAM之间传输数据(比如让ADC采集的温度数据直接存进RAM),大大降低CPU负担,让CPU能专注处理更重要的任务。

IAMIF12的博客 1038

【LaTex】LaTex的下载与安装(2025新手小白超详细、超简洁 Windows系统)

安装地点(1)texlive的安装:首先打开下载好的安装包,找到这个文件前面缺少了一页emm我去截取其他人的作为示范然后点击安装安装时间较久,大概要一个小时左右。具体要看个人电脑性能情况。如图显示如上图,则安装成功。图中是TeXstudio 4.8.7版本针对不同操作系统和使用场景的安装包 ,区别如下:(按需求下载)

爱学习的capoo的博客 5097

qt中的拖拽及其使用技巧

关于qt中的拖放操作,首先可以看这篇官方文档:http://doc.qt.io/qt-5.5/dnd.html 一、QDrag 首先是创建QDrag,可以在mousePressEvent或者mouseMoveEvent中创建。 void DragDropWidget::mousePressEvent(QMouseEvent *event) { if (event->butt...

weixin_33994429的博客 124

【基于 CasADi 的欠驱动无人船实时非线性模型预测控制(NMPC)实现 Visual Studio 2022 C++】

本文介绍了基于CasADi和IPOPT在Visual Studio 2022 C++环境下实现的欠驱动无人船实时非线性模型预测控制(NMPC)方案。文章详细阐述了NMPC基本原理、欠驱动无人船动力学模型(包含状态变量和控制变量定义),并给出了C++实现的核心代码框架。该方案通过显式引入系统动力学模型和约束条件,在每个采样周期滚动优化控制序列,有效解决了欠驱动无人船的轨迹跟踪与避碰问题。文中还提供了VS2022配置CasADi环境的详细步骤,包括预编译包下载、工程属性设置等关键环节,为工程实现提供了完整的技术

vor234的博客 651

qml demo分析(externaldraganddrop-拖拽)

一、效果展示   客户端程序拖拽是一个很常见的需求,对于QWidget程序来说,需要重写如图1这么几个方法,通过重写这几个方法的逻辑,我们就可以控制鼠标拖拽的逻辑,糟糕的是QDrag执行exec后是一个阻塞主事件循环的操作,这个时候除了拖拽界面外,其他界面不能响应鼠标事件。作者之前就有过这么一个需要主界面响应的需求,当时我是重写了如图2所示的接口,来模拟程序拖拽。 图1 QWidget拖拽...

weixin_34107739的博客 146

华为OD机试 - 机器人活动区域(Python/JS/C/C++ 双机位C卷 200分)

本专栏收录于《华为OD机试真题(Python/JS/C/C++)》。刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新。现有一个机器人,可放置于 M × N的网格中任意位置,每个网格包含一个非负整数编号。当相邻网格的数字编号差值的绝对值小于等于 1 时,机器人可在网格间移动问题:求机器人可活动的最大范围对应的网格点数目。说明:1)网格左上角坐标为 (0, 0),右

学Java,找哪吒 1432

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

下一篇: 程序员电脑屏保画面,显示时间
照书抄代码
博客等级 码龄8年 32粉丝 50原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值