(二十九)QMimeData类与拖放事件

时间:2022-07-23 04:36:15

QMimeData 类

QMimeData类为记录自身MIME信息的数据提供了一个容器

 

#include <QMimeData>

 

继承自QObject

 

详细描述

QMimeData类为记录自身MIME信息的数据提供了一个容器

QMimeData通常用于描述可以被存储在剪贴板、可以被通过拖拽机制传输的信息。QMimeData对象将他们持有的数据与相应的MIME类型相关联,以确保信息可以在两个应用程序之间被安全的传输或是在同一个应用中被安全的复制

 

QMimeData对象通常使用new来创建,并且支持QDrag或QClipboard对象,这使得Qt能够管理他们使用的内存

 

单个QMimeData对象可以同时使用几种不同的格式存储同一数据, formats() 函数按优先级的顺序返回一个可用格式的list, data()函数返回与一个MIME类型关联的原始数据,使用setData()函数为MIME类型设置数据

 

对于最常见的MIME类型,QMimeData类提供了方便函数来访问数据

(二十九)QMimeData类与拖放事件

 

比如,如果要一个widget接收URL拖拽,你应该这样写:

void MyWidget::dragEnterEvent(QDragEnterEvent*event)
 {
     if(event->mimeData()->hasUrls())
        event->acceptProposedAction();
 }
 
 voidMyWidget::dropEvent(QDropEvent *event)
 {
     if(event->mimeData()->hasUrls()) {
        foreach (QUrl url, event->mimeData()->urls()) {
            ...
        }
     }
 }


 

下面是在一个QMimeData对象中存储客户数据的三种方式:

1、  通过setData()函数可以将客户数据可以作为一个QByteArray直接存储在QMimeData对象中,例如:

QByteArray csvData = ...;
 
 QMimeData *mimeData = new QMimeData;
 mimeData->setData("text/csv",csvData);
 


2、子类化QMimeData并重写 hasFormat(), formats(), 与 retrieveData()函数

3、如果拖放操作在单一应用程序中发生,子类化QMImeData并加入额外的数据成员,再在接收对象的拖放事件处理函数中使用qobject_cast(),例如

 

void MyWidget::dropEvent(QDropEvent *event)
 {
     const MyMimeData *myData =
             qobject_cast<const MyMimeData *>(event->mimeData());
     if (myData) {
         // access myData's data directly (not through QMimeData's API)
     }
 }
 

Qt中的拖放事件

拖放一个文件进入窗口时将触发拖放事件

每一个QWidget对象都能处理拖放事件

拖放事件处理函数:

void dragEnterEvent ( QDragEnterEvent * event )[virtualprotected]

void dropEvent ( QDropEvent * event ) [virtualprotected]

 

自定义拖放事件

1、调用接收对象的void setAcceptDrops (bool on )成员函数设置acceptDrops属性

2、重写dragEnterEvent()函数并判断MIME类型

1)、期望数据 e->acceptProposedAction();

2)、其他数据 e->ignore();

3、重写dropEvent()函数并判断MIME类型

1)、期望数据: 从事件对象中获取MIME数据并处理

2)、其他数据: e->ignore();

 

//Widget.h

#ifndef WIDGET_H
#define WIDGET_H
 
#include <QtGui/QWidget>
 
class Widget : public QWidget
{
   Q_OBJECT
protected:
   void dragEnterEvent(QDragEnterEvent* e);   //重写声明
   void dropEvent(QDropEvent* e);                       //重写声明
public:
   Widget(QWidget *parent = 0);
   ~Widget();
};
 
#endif // WIDGET_H


 

//Widget.cpp

 

#include "Widget.h"
#include <QDragEnterEvent> //头文件
#include <QDropEvent>
#include <QDebug>
#include <QList>
#include <QUrl>
 
Widget::Widget(QWidget *parent) :QWidget(parent)
{
   setAcceptDrops(true);    //默认不接受,需主动设置
}
 
voidWidget::dragEnterEvent(QDragEnterEvent* e)      //重写拖事件处理函数
{
   if( e->mimeData()->hasUrls() )                  //判断拖事件里的mimeData对象是否包含资源定位符
    {
       e->acceptProposedAction();             //期望数据
    }
   else
    {
       e->ignore();                                  //其他数据,给父组件机会去判断他是否需要处理
    }
}
 
void Widget::dropEvent(QDropEvent* e)        //重写放事件处理函数
{
   if( e->mimeData()->hasUrls() )                 
    {
       QList<QUrl> list = e->mimeData()->urls();       //获取资源定位符
 
       for(int i=0; i<list.count(); i++)
       {
           qDebug() << list[i].toLocalFile();       //将资源定位符转化为本地文件路径
       }
    }
   else
    {
       e->ignore();              
    }
}
 
Widget::~Widget()
{
   
}


 

下面引入豆子空间的三篇博客加深理解:

Qt学习之路(52):拖放技术之一 http://devbean.blog.51cto.com/448512/280052

Qt学习之路(53):拖放技术之二 http://devbean.blog.51cto.com/448512/286796

Qt学习之路(54):自定义拖放数据对象 http://devbean.blog.51cto.com/448512/288742

 

 

 

 

 

 声明:
此文根据 狄泰学院唐老师的《QT实验分析教程》创作,并根据自身理解与官方文档对其进行了少许的扩展