Qt学习之路(52): 拖放技术之一

简介:
拖放 Drag and Drop,有时又被称为 DnD,是现代软件开发中必不可少的一项技术。它提供了一种能够在应用程序内部甚至是应用程序之间进行信息交换的机制,并且,操作系统与应用程序之间进行剪贴板的内容交换,也可以被认为是 DnD 的一部分。
DnD 其实是由两部分组成的:Drag 和 Drop。Drag 是将被拖放对象“拖动”,Drop 是将被拖放对象“放下”,前者一般是一个按下鼠标的过程,而后者则是一个松开鼠标的过程,这两者之间鼠标一直是被按下的。当然,这只是一种通常的情况,其他情况还是要看应用程序的具体实现。对于 Qt 而言,widget既可以作为 drag 对象,也可以作为 drop 对象,或者二者都是。
下面的一个例子来自 C++ GUI Programming with Qt 4, 2nd Edition。在这个例子中,我们创建一个程序,可以将系统中的文本文件拖放过来,然后在窗口中读取内容。
mainwindow.h
 
  1. #ifndef MAINWINDOW_H  
  2. #define MAINWINDOW_H  
  3.  
  4. #include <QtGui>  
  5.  
  6. class MainWindow : public QMainWindow  
  7. {  
  8.     Q_OBJECT  
  9.  
  10. public:  
  11.     MainWindow(QWidget *parent = 0);  
  12.     ~MainWindow();  
  13.  
  14. protected:  
  15.     void dragEnterEvent(QDragEnterEvent *event);  
  16.     void dropEvent(QDropEvent *event);  
  17.  
  18. private:  
  19.     bool readFile(const QString &fileName);  
  20.     QTextEdit *textEdit;  
  21. };  
  22.  
  23. #endif // MAINWINDOW_H 
mainwindow.cpp
 
  1. #include "mainwindow.h"  
  2.  
  3. MainWindow::MainWindow(QWidget *parent)  
  4.     : QMainWindow(parent)  
  5. {  
  6.     textEdit = new QTextEdit;  
  7.     setCentralWidget(textEdit);  
  8.  
  9.     textEdit->setAcceptDrops(false);  
  10.     setAcceptDrops(true);  
  11.  
  12.     setWindowTitle(tr("Text Editor"));  
  13. }  
  14.  
  15. MainWindow::~MainWindow()  
  16. {  
  17. }  
  18.  
  19. void MainWindow::dragEnterEvent(QDragEnterEvent *event)  
  20. {  
  21.     if (event->mimeData()->hasFormat("text/uri-list")) {  
  22.         event->acceptProposedAction();  
  23.     }  
  24. }  
  25.  
  26. void MainWindow::dropEvent(QDropEvent *event)  
  27. {  
  28.     QList<QUrl> urls = event->mimeData()->urls();  
  29.     if (urls.isEmpty()) {  
  30.         return;  
  31.     }  
  32.  
  33.     QString fileName = urls.first().toLocalFile();  
  34.     if (fileName.isEmpty()) {  
  35.         return;  
  36.     }  
  37.  
  38.     if (readFile(fileName)) {  
  39.         setWindowTitle(tr("%1 - %2").arg(fileName, tr("Drag File")));  
  40.     }  
  41. }  
  42.  
  43. bool MainWindow::readFile(const QString &fileName)  
  44. {  
  45.     bool r = false;  
  46.     QFile file(fileName);  
  47.     QTextStream in(&file);  
  48.     QString content;  
  49.     if(file.open(QIODevice::ReadOnly)) {  
  50.         in >> content;  
  51.         r = true;  
  52.     }  
  53.     textEdit->setText(content);  
  54.     return r;  
main.cpp
 
  1. #include <QtGui/QApplication>  
  2. #include "mainwindow.h"  
  3.  
  4. int main(int argc, char *argv[])  
  5. {  
  6.     QApplication a(argc, argv);  
  7.     MainWindow w;  
  8.     w.show();  
  9.     return a.exec();  
这里的代码并不是很复杂。在MainWindow中,一个QTextEdit作为窗口中间的widget。这个类中有两个protected的函数:dragEnterEvent() 和 dropEvent(),这两个函数都是继承自 QWidget,看它们的名字就知道这是两个事件,而不仅仅是signal。
在构造函数中,我们创建了 QTextEdit 的对象。默认情况下,QTextEdit 可以接受从其他的应用程序拖放过来的文本类型的信息。如果用户把一个文件拖到这里面,那么就会把文件名插入到文本的当前位置。但是我们希望让MainWindow 读取文件内容,而不仅仅是插入文件名,所以我们在MainWindow中对 drop 事件进行了处理,因此要把QTextEdit的setAcceptDrops()函数置为false,并且把MainWindow的setAcceptDrops()置为true,以便让MainWindow对 drop 事件进行处理。
当用户将对象拖动到组件上面时,dragEnterEvent()函数会被回调。如果我们在事件处理代码中调用 acceptProposeAction() 函数,我们就可以向用户暗示,你可以将拖动的对象放在这个组件上。默认情况下,组件是不会接受拖放的。如果我们调用了这样的函数,那么Qt会自动地以光标来提示用户是否可以将对象放在组件上。在这里,我们希望告诉用户,窗口可以接受拖放。因此,我们首先检查拖放的MIME类型。MIME类型为 text/uri-list 通常用来描述一个 URI 的列表。这些 URI 可以是文件名,可以是 URL或者其他的资源描述符。MIME类型由 Internet Assigned Numbers Authority (IANA) 定义,Qt 的拖放事件使用MIME类型来判断拖放对象的类型。关于 MIME类型的详细信息,请参考  http://www.iana.org/assignments/media-types/.
当用户将对象释放到组件上面时,dropEvent() 函数会被回调。我们使用 QMimeData::urls()来或者 QUrl 的一个list。通常,这种拖动应该只用一个文件,但是也不排除多个文件一起拖动。因此我们需要检查这个list是否为空,如果不为空,则取出第一个。如果不成立,则立即返回。最后我们调用 readFile() 函数读取文件内容。关于读取操作我们会在以后的章节中详细说明,这里不再赘述。
好了,至此我们的小程序就解释完毕了,运行一下看看效果吧!
对于拖动和脱离,Qt 也提供了类似的函数:dragMoveEvent() 和 dragLeaveEvent(),不过对于大部分应用而言,这两个函数的使用率要小得多。


本文转自 FinderCheng 51CTO博客,原文链接:http://blog.51cto.com/devbean/280052

相关文章
|
29天前
|
Linux 数据处理 C++
Linux系统编程 C/C++ 以及Qt 中的零拷贝技术: 从底层原理到高级应用(一)
Linux系统编程 C/C++ 以及Qt 中的零拷贝技术: 从底层原理到高级应用
69 0
|
29天前
|
存储 Linux API
Linux系统编程 C/C++ 以及Qt 中的零拷贝技术: 从底层原理到高级应用(三)
Linux系统编程 C/C++ 以及Qt 中的零拷贝技术: 从底层原理到高级应用
30 1
|
29天前
|
消息中间件 Linux 数据处理
Linux系统编程 C/C++ 以及Qt 中的零拷贝技术: 从底层原理到高级应用(二)
Linux系统编程 C/C++ 以及Qt 中的零拷贝技术: 从底层原理到高级应用
30 1
|
29天前
|
测试技术 数据库 C++
Qt C++拖放事件探索之旅:多方法深入解析
Qt C++拖放事件探索之旅:多方法深入解析
115 1
|
1月前
|
编解码 供应链 开发工具
英飞凌采用Qt图形解决方案增强Traveo T2G MCU系列,实现智能渲染技术
在竞争激烈的全球半导体市场,制造商一直在努力缩短产品上市时间。同时,他们对流畅、高分辨率图形显示器的需求也在日益增长。
|
7月前
|
传感器 物联网 Unix
QT跨平台开发技术总结
QT跨平台开发技术总结
96 0
|
12月前
|
数据可视化
Qt开发技术:Q3D图表开发笔记(三):Q3DSurface三维曲面图介绍、Demo以及代码详解
qt提供了q3d进行三维开发,虽然这个框架没有得到大量运用也不是那么成功,性能上也有很大的欠缺,但是普通的点到为止的应用展示还是可以的。其中就包括华丽绚烂的三维图表,数据量不大的时候是可以使用的。前面介绍了基础的q3d散点图、柱状图,本篇介绍基础的三维曲面图。Q3DSurface类提供了渲染3D曲面图的方法。该类使开发人员能够渲染3D表面图,并通过自由旋转场景来查看它们。可以通过QSurface3DSeries控制曲面的视觉财产,例如绘制模式和着色。
|
数据可视化
Qt开发技术:Q3D图表开发笔记(二):Q3DBar三维柱状图介绍、Demo以及代码详解
qt提供了q3d进行三维开发,虽然这个框架没有得到大量运用也不是那么成功,性能上也有很大的欠缺,但是普通的点到为止的应用展示还是可以的。   其中就包括华丽绚烂的三维图表,数据量不大的时候是可以使用的。   上一篇介绍了基础的q3d散点图,本篇介绍基础的柱状图。
Qt开发技术:Q3D图表开发笔记(二):Q3DBar三维柱状图介绍、Demo以及代码详解
|
数据可视化
Qt开发技术:Q3D图表开发笔记(一):Q3DScatter三维散点图介绍、Demo以及代码详解
qt提供了q3d进行三维开发,虽然这个框架没有得到大量运用也不是那么成功,性能上也有很大的欠缺,但是普通的点到为止的应用展示还是可以的。
Qt开发技术:Q3D图表开发笔记(一):Q3DScatter三维散点图介绍、Demo以及代码详解
|
存储 缓存 数据可视化
Qt开发技术:图形视图框架(二)场景QGraphicsScene、QGraphicsItem与QGraphicsView详解
Qt开发技术:图形视图框架(二)场景QGraphicsScene、QGraphicsItem与QGraphicsView详解
Qt开发技术:图形视图框架(二)场景QGraphicsScene、QGraphicsItem与QGraphicsView详解

推荐镜像

更多