在窗口中拖动图片

本文介绍了如何在C++中使用Qt框架创建一个带有图片的窗口,实现鼠标点击事件触发的拖放功能,支持自定义MIME类型,以及处理拖动进入、移动和放下事件。
摘要由CSDN通过智能技术生成
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QDebug>

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
protected:
    void mousePressEvent(QMouseEvent *event);//鼠标按下事件
    void dragEnterEvent(QDragEnterEvent *event);//拖动进入事件
    void dragMoveEvent(QDragMoveEvent *event);//拖动事件
    void dropEvent(QDropEvent * event);//放下事件
private:
};
#endif // MAINWINDOW_H
#include "mainwindow.h"
#include <QDragEnterEvent>
#include <QMouseEvent>
#include <QDragMoveEvent>
#include <QDropEvent>
#include <QLabel>
#include <QPainter>
#include <QMimeData>
#include <QDrag>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    resize(600,600);
    setAcceptDrops(true);//设置窗口部件可以接收拖入
    QLabel *label = new QLabel(this);//创建标签
    QPixmap pix(":/image/222.png");
    label->setPixmap(pix);//添加图片
    label->resize(pix.size());//设置标签大小为图片的大小
    label->move(100,100);
    label->setAttribute(Qt::WA_DeleteOnClose);//当窗口关闭时销毁图片
}
MainWindow::~MainWindow()
{
}

void MainWindow::mousePressEvent(QMouseEvent *event)
{
    qDebug() << "1";
    //![第一步:获取图片]
    //将鼠标指针所在位置的部件强制转换为QLabel类型
    QLabel *child = static_cast<QLabel*>(childAt(event->pos()));
    if(!child->inherits("QLabel")){
        return;//如果部件不是QLabel 则直接返回
    }
    QPixmap pixmap = *child->pixmap();//获取QLabel中的图片
    //![第二步:自定义MIME类型]
    QByteArray item_data;//创建字节数组
    QDataStream data_stream(&item_data, QIODevice::WriteOnly);//创建数据流
    //将图片信息,位置信息输入到字节数组中
    //位置信息是当前鼠标指针的坐标减去图片左上角的坐标而得到的差值
    data_stream << pixmap << QPoint(event->pos() - child->pos());
    //![第三步:将数据放入QMimeData中]
    QMimeData *mime_data = new QMimeData;//创建QMimeData用来存放要移动的数据
    //将字节数组放人MimeData中,这里的MIE类型是我们自己定义的
    mime_data->setData("my_image/png",item_data);
    //![第四步:将QMimeData数据放入QDrag中]
    QDrag *drag = new QDrag(this);//创建QDrag,它用来移动数据
    drag->setMimeData(mime_data);
    drag->setPixmap(pixmap);//在移动过程中显示图片,若不设置则默认显示一个小矩形
    drag->setHotSpot(event->pos() - child->pos());//拖动时鼠标指针的位置不变
    //![第五步:给原图片添加阴影]
    QPixmap temp_pixmap = pixmap;//使原图片添加阴影
    QPainter painter;//创建OPainter,用来绘制 QPixmap
    painter.begin(&temp_pixmap);
    //在图片的外接矩形中添加一层透明的淡黑色形成阴影效果
    painter.fillRect(pixmap.rect(), QColor(127, 127, 127, 127));
    painter.end();
    child->setPixmap(temp_pixmap);
    //![第六步:执行拖放操作]
    //设置拖放可以是移动和复制操作,默认是复制操作,QDrag类exec函数不影响主事件循环
    if(drag->exec(Qt::CopyAction | Qt::MoveAction, Qt::CopyAction) == Qt::MoveAction){
        child->close();//如果是移动操作,那么拖放完成后关闭原标签
    }else{
        child->show();//如果是复制操作,那么拖放完成后显示标签
        child->setPixmap(pixmap);//显示原图片,不再使用阴影
    }
    qDebug() << "5";
}

void MainWindow::dragEnterEvent(QDragEnterEvent *event)
{
    qDebug() << "2";
    //如果有我们定义的MIE类型数据,则进行移动操作
    if(event->mimeData()->hasFormat("my_image/png")){
        event->setDropAction(Qt::MoveAction);
        event->accept();//控制事件是否传播
    }else{
        event->ignore();
    }
}

void MainWindow::dragMoveEvent(QDragMoveEvent *event)
{
    qDebug() << "3";
    if(event->mimeData()->hasFormat("my_image/png")){
        event->setDropAction(Qt::MoveAction);
        event->accept();
    }else{
        event->ignore();
    }
}

void MainWindow::dropEvent(QDropEvent *event)
{
    qDebug() << "4";
    if(event->mimeData()->hasFormat("my_image/png")){
        QByteArray item_data = event->mimeData()->data("my_image/png");
        QDataStream data_stream(&item_data, QIODevice::ReadOnly);
        QPixmap pixmap;
        QPoint offset;
        //使用数据流将字节数组中的数据读入到QPixmap和QPoint变量中
        data_stream >> pixmap >> offset;
        //新建标签,为其添加图片,并根据图片大小设置标签的大小
        QLabel *new_label = new QLabel(this);
        new_label->setPixmap(pixmap);
        new_label->resize(pixmap.size());
        //让图片移动到放下的位置,不设置的话,图片会默认显示在(0.0)点即窗口左上角
        new_label->move(event->pos() - offset);
        new_label->show();
        new_label->setAttribute(Qt::WA_DeleteOnClose);
        event->setDropAction(Qt::MoveAction);
        event->accept();
    }else{
        event->ignore();
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值