Qt中的拖放操作
- 拖放操作分为拖动(Drag)和放下两种操作,当数据被拖动时,会被存储为MIME类型。
- Qt中使用QMimeData类来表示MIME类型的数据,并使用QDrag类来完成数据的转移,而整个拖放操作都是在几个鼠标事件和拖放事件中完成的。
示例——使用拖放打开文件
下面来看一个很简单的例子,就是将桌面上的.txt文件拖入到 Text Edit中。新建 Qt Widgets应用,基类选择 QMainWindow,并向界面上拖入一个Text Edit部件
- 在mainwindow.h文件中添加如下内容:
protected:
void dragEnterEvent(QDragEnterEvent * event); // 拖动进入事件
void dropEvent(QDropEvent * event); // 放下事件
- 然后到mainwindow.cpp添加如下头文件:
#include <QDragEnterEvent>
#include <QUrl>
#include <QFile>
#include <QTextStream>
#include <QMimeData>
- 最后对两个事件处理函数进行定义
void MainWindow::dragEnterEvent(QDragEnterEvent *event) // 拖动进入事件
{
if(event->mimeData()->hasUrls()) { // 数据中是否包含 URL
event->acceptProposedAction(); // 如果是则接受动作
}
else event->ignore(); // 否则忽略该事件
}
void MainWindow::dropEvent(QDropEvent *event) // 放下事件
{
const QMimeData * mimeData = event->mimeData(); // 获取MIME数据
if(mimeData->hasUrls()) { // 如果数据中包含URL
QList <QUrl> urlList = mimeData->urls(); // 获取URL列表
//将其中第一个URL表示为本地文件路径
QString fileName = urlList.at(0).toLocalFile(); // 返回格式化为本地文件路径的URL的路径
if(!fileName.isEmpty()) { // 如果文件路径不为空
QFile file(fileName); // 建立 QFile 对象并且以只读的方式打开该文件
if(!file.open(QIODevice::ReadOnly)) return; //只读方式打开失败则返回
QTextStream in(&file); // 建立文本流对象
ui->textEdit->setText(in.readAll()); // 将文件中所有内容读入编辑器
}
}
}
- 在MainWindow类构造函数中添加下面一行代码:
setAcceptDrops(true); //设置主窗口可以接收放下事件,默认为 flase
- 常用MIME类型数据处理函数
测试函数 | 获取函数 | 设置函数 | MIME类型 |
---|---|---|---|
hasText( ) | text( ) | setText( ) | text/plain |
hasHtml( ) | html( ) | setHtml( ) | text/html |
hasUrls( ) | urls( ) | setUrls( ) | text/uri-list |
hasImage( ) | imageData( ) | setImageData( ) | image/* |
hasColor( ) | colorData( ) | setColorData( ) | application/x-color |
拖动发生过程解析
当鼠标拖拽一个数据进入主窗口是,就会触发dragEnterEvent()
事件处理函数,从而获取其中的MIME数据;然后查看他是否包含URL路径。因为拖入文本实际上就是拖入了它的路径,这就是event->mimeData( )->hasUrls( )
实现的功能。如果有这样的数据,就接受它,否则忽略该事件。当松开鼠标左键时,将数据放入主窗口(我们这里是重新实现了主窗口的拖放动作相应的事件函数)时就会触发dropEvent( )
事件处理函数,这里获取了MIME数据中的URL列表。因为拖入的只有一个文件,所以获取了列表中的第一个条目,并使用toLocalFile( )
函数将它转换为本地文件路径。然后使用QFile和QTextStream将文件中的数据读入的编辑器中。
现在运行程序,然后从桌面上将一个文本文件拖入程序的主窗口界面(不是里面的Text Edit部件,我们这里是重新实现了主窗口的拖放动作相应的事件函数),可以看到文本编辑器中显示了文本文件中的内容。