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

效果预览

拖拽实现效果
代码链接:https://download.csdn.net/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();
    }
}

发布了3 篇原创文章 · 获赞 1 · 访问量 609

猜你喜欢

转载自blog.csdn.net/ASCE_Python/article/details/104240792
今日推荐