简述:
拖放 ,Drag and Drop,又称DnD,提供了一种能够在应用程序内部甚至应用程序之间信息交换的机制。Drag 是将被拖放对象“拖动”,Drop 是将被拖放对象“放下”,前者一般是一个按下鼠标的过程,而后者则是一个松开鼠标的过程,这两者之间鼠标一直是被按下的。拖放事件函数是一个筛选事件并放置的函数。实现需要分三步走:
1、设置接受拖放事件
首先需要设置setAcceptDrops(true)来接受放下事件
2、实现dragEnterEvent()
这是一个Protected函数,当用户将对象拖动到组件上面时,dragEnterEvent()函数会被回调。在dragEnterEvent()事件中对拖入的对象进行筛选,判断mimeData的类型是否是你能处理的,如果是,则调用event->acceptProposedAction()放行。
3、实现dropEvent()
拖放结束后会产生dropEvent()事件,在dropEvent()实现最后的放置操作。
4、实例
mainwindow.h
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QTextEdit> class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = 0); ~MainWindow(); protected: void dragEnterEvent(QDragEnterEvent *event); void dropEvent(QDropEvent *event); private: bool readFile(const QString &fileName); QTextEdit *textEdit; }; #endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { textEdit = new QTextEdit; setCentralWidget(textEdit); /*** * 默认情况下,QTextEdit 可以接受从其他的应用程序拖放过来的文本类型的信息。 * 如果用户把一个文件拖到这里面,那么就会把文件名插入到文本的当前位置。但是 * 我们希望让MainWindow 读取文件内容,而不仅仅是插入文件名,所以我们在 * MainWindow中对 drop 事件进行了处理,因此要把QTextEdit的setAcceptDrops() * 函数置为false,并且把MainWindow的setAcceptDrops()置为true, * 以便让MainWindow对 drop 事件进行处理。 **/ textEdit->setAcceptDrops(false); setAcceptDrops(true); setWindowTitle(tr("Text Editor")); } MainWindow::~MainWindow() { } void MainWindow::dragEnterEvent(QDragEnterEvent *event) { if (event->mimeData()->hasFormat("text/uri-list")) { event->acceptProposedAction(); } } void MainWindow::dropEvent(QDropEvent *event) { QList<QUrl> urls = event->mimeData()->urls(); if (urls.isEmpty()) { return; } QString fileName = urls.first().toLocalFile(); if (fileName.isEmpty()) { return; } if (readFile(fileName)) { setWindowTitle(tr("%1 - %2").arg(fileName, tr("Drag File"))); } } bool MainWindow::readFile(const QString &fileName) { bool r = false; QFile file(fileName); QTextStream in(&file); QString content; if(file.open(QIODevice::ReadOnly)) { in >> content; r = true; } textEdit->setText(content); return r; }
main.cpp
#include <QApplication> #include "mainwindow.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); }
样例二:
只提供dragEnterEvent()函数和dropEvent()函数
void MainWindow::dragEnterEvent(QDragEnterEvent* event) { foreach(QUrl url, event->mimeData()->urls()){ QString filename = url.toLocalFile(); QFileInfo fi(filename); if (fi.suffix().toUpper() == "TXT") { event->acceptProposedAction(); return; } if (fi.fileName().toLower() == "debug.hdf") { event->acceptProposedAction(); return; } if (fi.fileName().toLower() == "fram_default_table.txt") { event->acceptProposedAction(); return; } } } void MainWindow::dropEvent(QDropEvent* event) { foreach(QUrl url, event->mimeData()->urls()) { QString filename = url.toLocalFile(); QFileInfo fi(filename); if (fi.suffix().toUpper() == "TXT") { loadFile(filename); break; } if (fi.fileName().toLower() == "debug.hdf") { QFile::copy(filename, QApplication::applicationDirPath() + "/debug.hdf"); QMessageBox::information(this, QApplication::applicationName(), "Debug file copied. Restart the application to activate debug session."); break; } if (fi.fileName().toLower() == "fram_default_table.txt") { QFile::copy(filename, QApplication::applicationDirPath() + "/fram_default_table.txt"); QMessageBox::information(this, QApplication::applicationName(), "Debug file copied. Restart the application to activate debug session."); break; } } }