- 论坛徽章:
- 0
|
在做图形界面时,我们经常会遇到需要实现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);
dataStreampos()
- 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();
}
}
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/72991/showart_1999560.html |
|