您的位置:首页 > 编程语言 > Qt开发

QT中拖拽的实现(附示例代码)

2010-10-10 18:22 666 查看
QT中的Drag and Drop的详细介绍参见:http://doc.qt.nokia.com/4.0/dnd.html

下面主要介绍一下Drag and Drop的Demo(下载),先附上一份效果图:





这是一个拼图的Demo,左边是原图,右边是打散的图,拖动小方格可以实现不同的方格内的图片交换,此外程序还支持手动拖入原图片。

代码中主要的类是一个DragWidget

它实现了以下几个方法。

void dragEnterEvent(QDragEnterEvent *dragEvent);
void dragLeaveEvent(QDragLeaveEvent *dragEvent);
void dragMoveEvent(QDragMoveEvent *dragEvent);
void dropEvent(QDropEvent *dragEvent);
void mousePressEvent(QMouseEvent *mouseEvent);

Drag执行的流程是:

Drag是从drag->exec()开始的,此时将开启进入一个新的事件循环,然后在拖动的过程中会在下面三个事件中交替:





其中DragEnter是有拖动进入该Widget时触发的,对应的DragLeave则是拖动离开时触发的,而DragMove就是鼠标拖动的时候触发的。

最后当鼠标释放的时候将触发dragEvent,此时将决定拖拽的结果。

回头看一下Drag的触发,和大多数系统一样,一个Drag可能是从控件外触发的,即将外部的数据拖入,也可以是从控件内部触发,即手动生成一个QDrag对象。在示例代码中,这两种方式都会有接触。

再聊聊拖动的机制,其实拖动就是将一处的数据移动或者复制到另外一处,在QT中拖动所承载的数据使用QMimeData表示的,它可以用来表示许多Mime Type的集合。一个Mime Type即有format和data两部分组成,format即指示了如何解析对应的data。更详细的定义可以参考:http://en.wikipedia.org/wiki/MIME

最后简单地介绍一些重要的代码片段

DragWidget中使用三个数组来表示对于的数据:


QList<QPixmap> mImgList; //image per block
QList<QRect> mPieceList; //position per block
QList<QPoint> mPosList; //correct per image


void mousePressEvent(QMouseEvent *mouseEvent);

QPoint point = mPosList[find];
QPixmap image = mImgList[find];
QRect rect = mHighlightRect;
mPieceList.removeAt(find);//.remove(mHighlightRect);
mImgList.removeAt(find);
mPosList.removeAt(find);
if (checkMatch(rect, point))
--mInPlace;
QByteArray data;
QDataStream stream(&data, QIODevice::WriteOnly);
stream << image << point;
QDrag* drag = new QDrag(this);
QMimeData* mimeData = new QMimeData;
mimeData->setData("application/x-dragitemdata", data);
drag->setMimeData(mimeData);
drag->setPixmap(image);
drag->setHotSpot(mouseEvent->pos() - mHighlightRect.topLeft());
if (0 == drag->exec(Qt::MoveAction)){


在mousePress的时候开启一个Drag,定义一个自己的Mime Type->“application/x-dragitemdata”,将需要的数据打包进去。

void dropEvent(QDropEvent *dragEvent);

if (dragEvent->mimeData()->hasFormat("application/x-dragitemdata"))
{
QRect targetRect = targetBlock(dragEvent->pos());
QByteArray data = dragEvent->mimeData()->data("application/x-dragitemdata");
QDataStream stream(data);
QPixmap image;
QPoint point;
stream >> image >> point;
mImgList.append(image);
mPieceList.append(targetRect);
mPosList.append(point);
if (checkMatch(targetRect, point))
++mInPlace;


在drop消息中对数据进行解包,并判断是否放置到了合适的位置。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: