您的位置:首页 > 编程语言 > Qt开发

Qt:自定义拖放操作

2017-11-20 10:59 239 查看
功能:实现在一个窗口中任意拖动图片;

头文件:

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QtGui>
#include <QLabel>

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
源文件:

main.cpp

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

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

return a.exec();
}
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
setAcceptDrops(true);                           //接收拖放
QLabel *label = new QLabel(this);
QPixmap pixmap(":/new/prefix1/Image/m5.png");
label->setPixmap(pixmap);
label->resize(pixmap.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()));
if(!child->inherits("QLabel"))
{
return;
}
QPixmap pixmap = *child->pixmap();

//创建数据流
QByteArray itemData;
QDataStream dataStream(&itemData,QIODevice::WriteOnly);
dataStream << pixmap << QPoint(event->pos() - child->pos());
//自定义MIME
QMimeData *mimeData = new QMimeData;
mimeData->setData("myimage/png",itemData);
//创建拖动项
QDrag *drag = new QDrag(this);
drag->setMimeData(mimeData);
drag->setPixmap(pixmap);
drag->setHotSpot(event->pos() - child->pos());//设置热点保持鼠标点住图片时,位置不变
//将原图片添加阴影
QPixmap tempPixmap = pixmap;
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-&g
4000
t;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");
QDataStream dataStream(&itemData,QIODevice::ReadOnly);
QPixmap pixmap;
QPoint offset;
//使用数据流将字节数组中的数据读入到QPixmap和QPoint变量中
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();//驳回事件
}
}
运行效果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: