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

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()开始的,此时将开启进入一个新的事件循环,然后在拖动的过程中会在下面三个事件中交替:

 

DragCircle

其中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消息中对数据进行解包,并判断是否放置到了合适的位置。

转载于:https://www.cnblogs.com/chinese-zmm/archive/2010/10/10/1847275.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值