#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();
}
}