Qt拖放

转载自http://blog.chinaunix.net/uid-25749806-id-331673.html

想要在图形组件上启用拖放功能,可以使用QWidget上所继承下来的setAcceptDrops()方法,设定组件接受拖放动作,在拖放动作发生时,会 有相对应的QDragEnterEvent、QDragMoveEvent、QDragLeaveEvent与QDropEvent等事件发生,您可以重 新定义dragEnterEvent()、dragMoveEvent()、dragLeaveEvent()与dropEvent()等事件处理者,以 处理相对应的拖放事件,通常会使用的是dragEnterEvent()与dropEvent()。

以下是一个简单的拖放事件处理程序,您可以将图档拖放至QLabel上,QLabel会自动加载图片并显示出来:

  • ImageLabel.h

#ifndef IMAGE_LABEL_H
#define IMAGE_LABEL_H

#include <QLabel>

class QDragEnterEvent;
class QDropEvent;

class ImageLabel : public QLabel {
Q_OBJECT

public:
ImageLabel(QWidget *parent = 0);

protected:
void dragEnterEvent(QDragEnterEvent *event);
void dropEvent(QDropEvent *event);

private:
void readImage(const QString &fileName);
};

#endif
ImageLabel继承了QLabel,并且将重新定义dragEnterEvent()及dropEvent(),以处理 对应的拖放事件,readImage()则会在拖放图档至QLabel上时,将图片档案加载并设定给QLabel来显示,ImageLabel的实作如 下:

  • ImageLabel.cpp

#include<QDragEnterEvent>
#include <QDropEvent>
#include <QUrl>
#include <QFile>
#include <QTextStream>
#include "ImageLabel.h"

ImageLabel::ImageLabel(QWidget *parent) : QLabel(parent) {
this->setAcceptDrops(true);
}

void ImageLabel::dragEnterEvent(QDragEnterEvent *event) {
if(event->mimeData()->hasFormat("text/uri-list")) {
event->acceptProposedAction();
}
}

void ImageLabel::dropEvent(QDropEvent *event) {
QList<QUrl> urls = event->mimeData()->urls();
if (urls.isEmpty()) {
return;
}

QString fileName = urls.first().toLocalFile();
if (fileName.isEmpty()) {
return;
}

this->setWindowTitle(fileName);
readImage(fileName);
}

void ImageLabel::readImage(const QString &fileName) {
QPixmap pixmap(fileName);
this->setPixmap(pixmap);
this->resize(pixmap.width(), pixmap.height());
}
setAcceptDrops(true)设定接受拖放,当图片档案被拖入组件时,发生QDragEnterEvent并分派 给dragEnterEvent()处理。QDragEnterEvent的mimeData()方法传回QMimeData,当中包括了MIME (Multipurpose Internet MailExtensions)类型的相关信息,hasFormat("text/uri-list")测试是否含有文字信息的URI(Universal Resource Identifier),也可以使用hasUrls()来进行同样的测试。

当拖放行为开始执行时,执行拖放行为的一方会需要知道接受放置的另一方接受何种操作,例如拖放档案时,当拖放完成时,原档案是被复制或移动。执行拖放行为的一方会设定可被接受的动作,而接受放置的一方可选择接受何种动作,并传回相关信息给执行方,acceptProposedAction()的作用为接受执行拖放行为的一方所设定的预设动作。

当放置时会发生QDropEvent并分派给dropEvent()来处理,QMimeData的urls()取得所拖放档案的QUrl,由于您所拖放的 档案可能不只一个,所以urls()传回的是内含QUrl的QList对象,您取得第一个QUrl并取得文件名信息,再进行图文件的读取并设定至QLabel 上。

可以撰写以下的程序来执行:

  • main.cpp

#include <QApplication>
#include <QMainWindow>
#include "ImageLabel.h"
#include <QTextEdit>

int main(int argc, char **argv) {
QApplication app(argc, argv);

ImageLabel *imgLabel = new ImageLabel;
imgLabel->setWindowTitle("Drag & Drop");
imgLabel->setText("<center>Drag & Drop Imagehere</center>");
imgLabel->resize(300, 200);
imgLabel->show();

return app.exec();
}
执行时,组件若可以进行拖放,则会出现相关的光标以提醒用户,在Windows下是个「+」的光标:



有些组件默认即接受拖放行为,例如QLineEdit,您可以直接将文字拖曳至QLineEdit,这会将拖曳的文字置放至您置放的位置,若您想改变这个 行为,可以设定QLineEdit的setAcceptDrops()为false,然后设定其父组件的setAcceptDrops()为true,让 拖放事件传播至父组件,由父组件来处理拖放相关事件,以改变QLineEdit的预设拖放行为,例如让纯文本档案拖至QLineEdit时,可以自动加载 文字至QLineEdit中。

 

你可能感兴趣的:(Qt拖放)