效果预览
代码链接: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();
}
}