QT自定义拖放_图片的移动
定义拖放操作案例---在应用程序主窗口里面拖动图片显示到任意位置如下几步骤:
- 鼠标按下事件
- 获取图片
- 自定义MIME类型
- 将数据放入QMimeData中
- 将QMimeData数据放入QDrag中
- 给原图片添加阴影
- 执行放下操作
- 拖动进入事件
- 拖动事件
- 放下事件
- 这个例子是对图片进行移动,如果想对图片进行复制,则只需要将dragEnterEvent( )、dragMoveEvent( )、dropEvent( )这三个函数中的event->setDropAction( )函数中的参数改为Qt::CopyAction即可。
- 对于拖放操作的其他应用,比如根据移动的距离判断是否开始一个拖放操作,还有剪贴板QClipboard类,都可以在帮助中通过Drag and Drop关键字查看。
- 对于mousePressEvent( )中第6步的QDrag类的exec( )函数,它不会影响主事件循环,所以这时界面不会被冻结。 这个函数设置了支持复制和移动动作,设置复制为默认放下动作。 exec( )函数的返回类型由dropEvent( )中的设置决定。 这里判断了到底进行了什么操作,如果是移动操作,那么就删除原来的图片;如果是复制操作,就恢复原来的图片
#ifndef MAINWINDOW_PIC_MOVE_H #define MAINWINDOW_PIC_MOVE_H #include QT_BEGIN_NAMESPACE namespace Ui { class MainWindow_pic_move; } QT_END_NAMESPACE class MainWindow_pic_move : public QMainWindow { Q_OBJECT public: MainWindow_pic_move(QWidget *parent = nullptr); ~MainWindow_pic_move(); private: Ui::MainWindow_pic_move *ui; protected: void mousePressEvent(QMouseEvent *event);//鼠标按下事件 void dragEnterEvent(QDragEnterEvent *event);//拖入事件 void dragMoveEvent(QDragMoveEvent *event);//拖动事件 void dropEvent(QDropEvent *event);//释放事件,放下事件 }; #endif // MAINWINDOW_PIC_MOVE_H
#include "mainwindow_pic_move.h" #include "ui_mainwindow_pic_move.h" #include #include #include #include #include #include #include #include //QT自定义拖放 MainWindow_pic_move::MainWindow_pic_move(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow_pic_move) { ui->setupUi(this); setAcceptDrops(true); QLabel *q_lable=new QLabel(this); //QPixmap q_pixmap("../xx/xx.png"); QPixmap q_pixmap("../src5_8/荷花1.jpg"); q_lable->setPixmap(q_pixmap); q_lable->resize(q_pixmap.size());//设置图片的大小作为标签的大小 q_lable->move(100,100); q_lable->setAttribute(Qt::WA_DeleteOnClose);//关闭窗口销毁图片 } MainWindow_pic_move::~MainWindow_pic_move() { delete ui; } void MainWindow_pic_move::mousePressEvent(QMouseEvent *event) { //1.获取图片 //将鼠标指针所在位置的部件强制转换为Qlabel类型 QLabel *child=static_cast(childAt(event->pos())); if(!child->inherits("QLabel")) return;//部件不是QLabel直接返回 QPixmap pix_map=*child->pixmap();//获取QLabel的图片 //2自定义MIME类型 QByteArray item_data; QDataStream data_stream(&item_data,QIODevice::WriteOnly);//创建数据流 //将图片信息,位置信息输入到字节数组中 data_streamsetMimeData(mime_data); drag->setPixmap(pix_map);//在移动过程中显示图片,若不设置则默认显示一个小矩形 drag->setHotSpot(event->pos()-child->pos());//拖动时鼠标指针的位置不变 //5给原图片添加阴影 QPixmap temp_pixmap=pix_map;//使原图片添加阴影 QPainter painter2; painter2.begin(&temp_pixmap); //在图片的外接矩形中添加一层透明的淡黑色形成阴影效果 painter2.fillRect(pix_map.rect(),QColor(127,127,127,127)); painter2.end(); child->setPixmap(temp_pixmap);//在移动图片过程中,让原图片添加一层黑色的阴影 //6.执行拖放操作 if(drag->exec(Qt::CopyAction|Qt::MoveAction,Qt::CopyAction)==Qt::MoveAction)//设置拖放可以是移动和复制操作,默认是复制操作 { child->close();//如果是移动操作,那么拖放 完成后关闭原标签 } else { child->show();//如果是复制操作,那么拖放完成后显示标签图片 child->setPixmap(pix_map);//显示原图片,不再使用阴影 } } void MainWindow_pic_move::dragEnterEvent(QDragEnterEvent *event) { //拖动进入事件 if(event->mimeData()->hasFormat("myimage/png"))//如果有我们定义的MIME类型数据,则进行移动操作 { event->setDropAction(Qt::MoveAction); event->accept(); } else { event->ignore(); } } void MainWindow_pic_move::dragMoveEvent(QDragMoveEvent *event)//拖动事件 { if(event->mimeData()->hasFormat("myimage/png")) { event->setDropAction(Qt::MoveAction); event->accept(); } else { event->ignore(); } } void MainWindow_pic_move::dropEvent(QDropEvent *event) { if(event->mimeData()->hasFormat("myimage/png")) { QByteArray item_data=event->mimeData()->data("myimage/png"); QDataStream data_stream(&item_data,QIODevice::ReadOnly); QPixmap pix_map; QPoint offset; //使用数据流将字节数组中的数据读入到QPixmap和QPoint变量中 data_stream>>pix_map>>offset; //新建标签,为其添加图片,并根据图片大小设置标签的大小 QLabel *new_label =new QLabel(this); new_label->setPixmap(pix_map); new_label->resize(pix_map.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(); } }