原文:http://www.chineselinuxuniversity.net/articles/52558.shtml,并且参考《Qt学习之路》
拖放技术由两部分组成:拖Drag、放Drop。
拖:按下鼠标并且移动鼠标以拖动对象。
放:鼠标松开的过程。拖和放之间,鼠标是一直按着的。
下面的小程序实现了:当拖动具有某种属性的对象到窗体时,鼠标显示可以拖放。鼠标松开时,在窗体的label上显示文件路径。
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QtGui/QWidget>
class QLabel;
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = 0);
~Widget();
protected:
//鼠标被拖动到窗体上时,dragEnterEvent被调用
void dragEnterEvent(QDragEnterEvent *);
//在可以拖放的情况下,松开鼠标,dropEvent被调用
void dropEvent(QDropEvent *);
private:
//显示拖放对象的文件路径
QLabel *labelFileName;
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include <QLabel>
#include <QDragEnterEvent>
#include <QDropEvent>
#include <QUrl>
#include <QVBoxLayout>
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
labelFileName=new QLabel;
//设置labelFileName不接受拖放事件
labelFileName->setAcceptDrops(false);
//设置当前this(主窗体)接受拖放事件
setAcceptDrops(true);
QVBoxLayout *mainLayout=new QVBoxLayout;
mainLayout->addWidget(labelFileName);
setLayout(mainLayout);
}
Widget::~Widget()
{
}
/*
如果拖放的对象具有url属性,则鼠标变成可以拖放的标识,并可以接受拖放
否则,鼠标变成拒绝拖放的标识,即使鼠标松开,dropEvent也不会被调用
*/
void Widget::dragEnterEvent(QDragEnterEvent *event)
{
if(event->mimeData()->hasFormat("text/uri-list"))
{
event->acceptProposedAction();
}
}
/*
拖动的对象可能有多个,获得每个对象的本地url并显示
*/
void Widget::dropEvent(QDropEvent *event)
{
QList<QUrl> urls=event->mimeData()->urls();
if(urls.isEmpty())
return;
QString fileName;
QUrl url;
foreach(url,urls)
{
QString name=url.toLocalFile();
if(!name.isEmpty())
fileName+=name+"\n";
}
labelFileName->setText(fileName);
}
main.cpp
#include <QtGui/QApplication>
#include "widget.h"
#include <QTextCodec>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QTextCodec::setCodecForTr(QTextCodec::codecForLocale());
Widget w;
w.show();
return a.exec();
}