QT的 qdrag 和 qdrop功能在qt的"Puzzle"示例中有介绍。但是那个介绍是以QListWidget为基础的。本文以QWidget为基础,介绍如何实现拖放。拖放可以用QString作为信息载体,也可以使用html等类型。本文采用QByteArray。QByteArray允许程序员使用自定义的类型来作为信息载体。本文定义的类型是ST_INFO。
头文件:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QDrag>
#include <QDropEvent>
#include <QMouseEvent>
#include <QLineEdit>
#include <QResizeEvent>
#pragma pack(1)
struct ST_INFO
{
bool b;
int i;
};
#pragma pack()
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
QPointF m_pntPress;
bool m_bMimeAdded;
QLineEdit * m_pText1;
QLineEdit * m_pText2;
QLineEdit * m_pText3;
protected:
void mousePressEvent(QMouseEvent *);
void mouseMoveEvent(QMouseEvent *);
void dropEvent(QDropEvent *);
void dragEnterEvent(QDragEnterEvent *);
void dragMoveEvent(QDragMoveEvent *);
void resizeEvent(QResizeEvent *);
};
#endif // MAINWINDOW_H
#include "mainwindow.h"
#include <QApplication>
#include <QMimeData>
#include <QDebug>
#include <QTextStream>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
setAcceptDrops(true);
m_pText1 = new QLineEdit(this);
m_pText2 = new QLineEdit(this);
m_pText3 = new QLineEdit(this);
}
MainWindow::~MainWindow()
{
delete m_pText1;
delete m_pText2;
delete m_pText3;
}
void MainWindow::mouseMoveEvent(QMouseEvent *event)
{
if ((QLineF(event->screenPos(), m_pntPress)
.length() < QApplication::startDragDistance()) || m_bMimeAdded)
{
return;
}
m_bMimeAdded = true;
QDrag *drag = new QDrag(this);
QMimeData *mime = new QMimeData;
drag->setMimeData(mime);
QImage image("E:\\lena.jpg");
drag->setPixmap(QPixmap::fromImage(image).scaled(30, 40));
drag->setHotSpot(QPoint(15, 30));
QByteArray qba;
QString qstrTemp1 = m_pText1->text();
QString qstrTemp2 = m_pText2->text();
bool bTemp;
if(qstrTemp1.contains("true"))
{
bTemp = true;
}
else
{
bTemp = false;
}
ST_INFO stTemp = {bTemp, qstrTemp2.toInt()};
qba.resize(sizeof(stTemp));
memcpy(qba.data(), &stTemp, sizeof(stTemp));
mime->setData(tr("INFO"), qba);
drag->exec();
}
void MainWindow::mousePressEvent(QMouseEvent *e)
{
m_pntPress = e->screenPos();
m_bMimeAdded = false;
}
void MainWindow::dropEvent(QDropEvent *event)
{
MainWindow *source = qobject_cast<MainWindow *>(event->source());
if(source != this)
{
if (event->mimeData()->hasFormat("INFO"))
{
QByteArray pieceData = event->mimeData()->data("INFO");
ST_INFO stTemp;
memcpy(&stTemp, pieceData.data(), sizeof(stTemp));
QString qstrTemp;
QTextStream stream(&qstrTemp, QIODevice::WriteOnly);
stream<<"b = "<<stTemp.b<<" i = "<<stTemp.i;
m_pText3->setText(qstrTemp);
event->setDropAction(Qt::MoveAction);
event->accept();
}
else
{
event->ignore();
}
}
else
{
event->ignore();
}
}
void MainWindow::dragEnterEvent(QDragEnterEvent *event)
{
if (event->mimeData()->hasFormat("INFO"))
event->accept();
else
event->ignore();
}
void MainWindow::dragMoveEvent(QDragMoveEvent *event)
{
if (event->mimeData()->hasFormat("INFO")) {
event->setDropAction(Qt::MoveAction);
event->accept();
} else {
event->ignore();
}
}
void MainWindow::resizeEvent(QResizeEvent *e)
{
m_pText1->setGeometry(0,0,width()/2, height()/4);
m_pText2->setGeometry(0, height()/3, width()/2, height()/4);
m_pText3->setGeometry(width()/2, height()*2/3, width()/2, height()/4);
}
启动两个一模一样的应用。在第一个窗口中输入如下:
然后在第一个窗口中按下鼠标,拖向第二个窗口,松开:
可见,第一个窗口的信息被正确传入了第二个窗口。