QT 自定义拖放操作,拖拽时 显示图片,且给原图片加阴影

1、要点:

1、鼠标在移动过程中显示图片

2、拖动时鼠标指针在图片的位置不变

3、拖拽图片时,给原图片添加阴影

 

2、MainWindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

namespace Ui {
    class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
protected:
    void mousePressEvent(QMouseEvent *event); //鼠标按下事件
    void dragEnterEvent(QDragEnterEvent *event); //拖动进入事件
    void dragMoveEvent(QDragMoveEvent *event); //拖动事件
    void dropEvent(QDropEvent *event); //放下事件
private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

 

3、MainWindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QLabel>
#include <QMouseEvent>
#include <QDragEnterEvent>
#include <QDragMoveEvent>
#include <QDropEvent>
#include <QPainter>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    // 设置窗口部件可以接收拖入
    setAcceptDrops(true);

    // 创建标签
    QLabel *label = new QLabel(this);
    QPixmap pix("../yafeilinux.png");
    // 添加图片
    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)
{
    /*****第一步:获取图片******/

    // 将鼠标指针所在位置的部件强制转换为QLabel类型
    QLabel *child = static_cast<QLabel*>(childAt(event->pos()));
    // 如果部件不是QLabel则直接返回
    if(!child->inherits("QLabel")) return;
    // 获取QLabel中的图片
    QPixmap pixmap = *child->pixmap();

    /*****第二步:自定义MIME类型******/

    // 创建字节数组
    QByteArray itemData;
    // 创建数据流
    QDataStream dataStream(&itemData, QIODevice::WriteOnly);
    // 将图片信息,位置信息输入到字节数组中
    dataStream << pixmap << QPoint(event->pos() - child->pos());


    /*****第三步:将数据放入QMimeData中******/

    // 创建QMimeData,它用来存放要移动的数据
    QMimeData *mimeData = new QMimeData;
    // 将字节数组放入QMimeData中,这里的MIME类型是我们自己定义的
    mimeData->setData("myimage/png", itemData);


    /*****第四步:将QMimeData数据放入QDrag中******/

    // 创建QDrag,它用来移动数据
    QDrag *drag = new QDrag(this);
    drag->setMimeData(mimeData);
    // 在移动过程中显示图片,若不设置则默认显示一个小矩形
    drag->setPixmap(pixmap);
    // 拖动时鼠标指针的位置不变
    drag->setHotSpot(event->pos() - child->pos());

    /*****第五步:给原图片添加阴影******/

    // 使原图片添加阴影
    QPixmap tempPixmap = pixmap;
    // 创建QPainter,用来绘制QPixmap
    QPainter painter;
    painter.begin(&tempPixmap);
    // 在图片的外接矩形中添加一层透明的淡黑色形成阴影效果
    painter.fillRect(pixmap.rect(), QColor(127, 127, 127, 127));
    painter.end();
    // 在移动图片过程中,让原图片添加一层黑色阴影
    child->setPixmap(tempPixmap);

    /*****第六步:执行拖放操作******/


    // 设置拖放可以是移动和复制操作,默认是复制操作
    // 如果是移动操作,那么拖放完成后关闭原标签
    if (drag->exec(Qt::CopyAction | Qt::MoveAction, Qt::CopyAction)
               == Qt::MoveAction)
        child->close();
    // 如果是复制操作,那么拖放完成后显示标签
    // 显示原图片,不再使用阴影
    else {
        child->show();
        child->setPixmap(pixmap);
    }
}

// 拖动进入事件
void MainWindow::dragEnterEvent(QDragEnterEvent *event)
{
     // 如果有我们定义的MIME类型数据,则进行移动操作
     if (event->mimeData()->hasFormat("myimage/png")) {
             event->setDropAction(Qt::MoveAction);
             event->accept();
     } else {
         event->ignore();
     }
}

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

// 放下事件
void MainWindow::dropEvent(QDropEvent *event)
{
    if (event->mimeData()->hasFormat("myimage/png")) {
         QByteArray itemData = event->mimeData()->data("myimage/png");

         // 使用数据流将字节数组中的数据读入到QPixmap和QPoint变量中
         QDataStream dataStream(&itemData, QIODevice::ReadOnly);
         QPixmap pixmap;
         QPoint offset;
         dataStream >> pixmap >> offset;

         // 新建标签,为其添加图片,并根据图片大小设置标签的大小
         QLabel *newLabel = new QLabel(this);
         newLabel->setPixmap(pixmap);
         newLabel->resize(pixmap.size());

         // 让图片移动到放下的位置,不设置的话,图片会默认显示在(0,0)点即窗口左上角
         newLabel->move(event->pos() - offset);
         newLabel->show();
         newLabel->setAttribute(Qt::WA_DeleteOnClose);

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

4、main.cpp

#include <QtGui/QApplication>
#include "mainwindow.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}

 

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值