实现Drag and Drop的最简模型

转载 2012年03月30日 14:11:38
在做图形界面时,我们经常会遇到需要实现Drag & Drop的效果,即拖拽效果,例如在实现拼图游戏的时候,我们就需要能够用鼠标拖拽拼图块,然后在我们想要停下的地方松开鼠标左键,从而将该图块放置在我们指定的地方。
Qt对拖拽的支持是非常强大和全面的,但是无论是Qt自身所带的Demo还是网上的相关资料,都感觉复杂了,太多和Drag & Drop无必需联系的细节掩盖了改效果的实现主线。下面我实现了一个Drag & Drop效果的最简模型。
程序运行效果是,在对话框中会出现一只可爱的企鹅(item),然后可以通过鼠标左键对该企鹅进行拖拽(Drag & Drop)。
首先,我们需要从QLabel继承一个我们自己的类DragItem。之所以选择QLabel是因为该类比较基本,而且能够很好的、无边框得存在于对话框中。实现该类最重要的也是必须的一点是,要在其构造函数中创建一个QImage对象,然后通过setPixmap函数将其选入,代码如下:
DragItem::DragItem(QWidget *parent):QLabel(parent)
{
  QImage image (128, 128, QImage::Format_ARGB32);
  if (image.load("../icon.png") == false)
      QMessageBox::warning(this, "ERROR", "Load image error!");
  setPixmap (QPixmap::fromImage(image));
}
然后,我们还需要一个对话框用于显示该item,也就是起到容器的作用。该对话框类必须要在其构造函数中通过setAcceptDrops函数,将其AcceptDrops属性设置为true,否则无法进行拖拽。构造函数如下:
Dialog::Dialog(QWidget *parent): QDialog(parent), ui(new Ui::Dialog)
{
DragItem *item = new DragItem (this);
item->setAttribute(Qt::WA_DeleteOnClose);
item->show();
setMinimumSize (400, 400);
setWindowTitle (tr("Drag & Drop Simplest Demo"));
setAcceptDrops (true);
ui->setupUi(this);
}
然后关键就是实现三个事件响应函数,分别是:
void dragEnterEvent (QDragEnterEvent *event);
void dropEvent (QDropEvent *event);
void mousePressEvent (QMouseEvent *event);
dragEnterEvent函数在鼠标拖拽物件进入该对话框范围内是被触发;dropEvent是当用户在对话框范围内松开鼠标左键结束拖拽时被触发;mousePressEvent,顾名思义,就是当鼠标被按下(无论是左键、右键还是中轮)被触发。我们需要在mousePressEvent响应函数内,创建QMimeData数据对象,然后用QDrag实现最终的拖拽效果。mousePressEvent负责对传入的QMimeData进行辨析,如果是我们想要的拖拽文件类型,就接受这个拖拽信息,否则予以忽略。dropEvent要做的是当拖拽结束,我们需要在新的位置再创建一个item对象,而将原先位置的item删除(或者关闭),通知完全将原有的item属性复制到新创建的item对象中。
这三个函数的实现代码如下:
void Dialog::dragEnterEvent (QDragEnterEvent *event)
{
if (event->mimeData()->hasFormat("application/x-draganddrop"))
    event->accept();
else
    event->ignore();
}

void Dialog::dropEvent (QDropEvent *event)
{
if (event->mimeData()->hasFormat("application/x-draganddrop"))
{
    const QMimeData *mimeData = event->mimeData();
    QByteArray exData = mimeData->data("application/x-draganddrop");
    QDataStream dataStream (&exData, QIODevice::ReadOnly);
    QPoint pos;
    dataStream>>pos;
    DragItem *item = new DragItem (this);
    item->setAttribute (Qt::WA_DeleteOnClose);
    item->move(event->pos()-pos);
    item->show();
}
}

void Dialog::mousePressEvent (QMouseEvent *event)
{
if (event->button() != Qt::LeftButton)
{
    event->ignore();
    return;
}
DragItem *item = (DragItem *)(this->childAt(event->pos()));
if (item == NULL)
{
    event->ignore();
    return;
}
else
{
    QMimeData *mimeData = new QMimeData;
    QByteArray exData;
    QDataStream dataStream (&exData, QIODevice::WriteOnly);
    dataStream<<event->pos() - item->pos();
    mimeData->setData("application/x-draganddrop", exData);
    mimeData->setText(tr("Drag and Drop"));
    QDrag *drag = new QDrag (this);
    drag->setMimeData(mimeData);
    drag->setPixmap(*(item->pixmap()));
    drag->setHotSpot(event->pos() - item->pos());
    item->hide();
    if (drag->exec(Qt::MoveAction) == Qt::MoveAction)
      item->close();
    else
      item->show();
}
}

在QML应用中如何实现drag and drop功能

在这篇文章中,我们将展示如何在QML应用中实现drag and drop的功能。更多的阅读可以参照Qt SDK。...
  • UbuntuTouch
  • UbuntuTouch
  • 2015年06月16日 14:23
  • 1870

练习笔记:使用jQuery实现H5拖放(drag 和 drop)功能

遇到问题1: 在js里面可直接e.dataTransfer.setData("obj_add",e.target.id); 使用jQuery绑定事件时,需e.originalEvent.dataTr...
  • leiliz
  • leiliz
  • 2017年02月08日 14:46
  • 3466

html5篇——拖放(Drag和Drop)

好久没有更新html5了,继续更新html5,今天更新html5的拖放功能。 拖放,就是抓取一个对象后拖放到另一个位置。很常用的一个功能,在html5中,任何元素都能够拖放。 浏览器支持 Inter...
  • u010556394
  • u010556394
  • 2016年05月30日 17:23
  • 1274

用 QT实现拖放(drag-drop)功能

QT的 qdrag 和 qdrop功能在qt的"Puzzle"示例中有介绍。但是那个介绍是以QListWidget为基础的。本文以QWidget为基础,介绍如何实现拖放。拖放可以用QString作为信...
  • liji_digital
  • liji_digital
  • 2016年10月22日 12:01
  • 951

drag & drop 拖拽与拖放简介

DataTransfer 对象:退拽对象用来传递的媒介,使用一般为Event.dataTransfer。 draggable 属性:就是标签元素要设置draggable=true,否则不会有效果 ,例...
  • u012193330
  • u012193330
  • 2015年04月08日 21:38
  • 669

.NET中的Drag and Drop操作(二)

在上一篇文章介绍了在.NET中进行Drag和Drop操作的方法,以及底层的调用实现过程。实际是通过一个DoDragDrop的WIN32 API来监视拖拽过程中的鼠标,根据鼠标的位置获得IDropTra...
  • jumtre
  • jumtre
  • 2013年12月11日 11:21
  • 1846

HTML5 拖放Drag 和 drop用法以及事件介绍

设置元素为可拖放首先,为了使元素可拖动,把 draggable 属性设置为 true :拖拽事件 名称 作用 dragstart 在拖动时触发 dragend 在拖动完成时触发 ...
  • c_kite
  • c_kite
  • 2017年05月02日 20:34
  • 926

(搬运工)NGUI官网示例11 –Drag ; Drop(图标与物体拖拽放置)

为ListPanel创建一个空的游戏对象,并命名为DragDropContainer,reset一下,并为它添加一个Collider(NGUI->Attach a collider),如图所示 在D...
  • z9895512
  • z9895512
  • 2015年06月09日 16:46
  • 834

HTML5 drag & drop 拖拽与拖放简介

HTML5 drag & drop 拖拽与拖放简介 这篇文章发布于 2011年02月9日,星期三,20:58,归类于 js实例。 阅读 214710 次, 今日 220 次 by ...
  • p312011150
  • p312011150
  • 2017年05月09日 20:21
  • 89

WPF上一个简洁的DragDrop测试(例子)

需要一个类似拖放的功能,看到了网上《Very Simple WPF Drag and Drop Sample without Win32 Calls》的例子,写的很简洁,故转载到这里来,方便以后查询!...
  • lee353086
  • lee353086
  • 2013年11月08日 10:23
  • 4854
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:实现Drag and Drop的最简模型
举报原因:
原因补充:

(最多只允许输入30个字)