文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>Qt学习系列之五:实现Drag and Drop的最简模型

Qt学习系列之五:实现Drag and Drop的最简模型

时间:2009-07-17  来源:cjmdaixi

在做图形界面时,我们经常会遇到需要实现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();    } }
排行榜 更多 +
浴血混战官方下载

浴血混战官方下载

飞行射击 下载
检票员模拟器免广告下载

检票员模拟器免广告下载

模拟经营 下载
最终前哨最终版手机版下载

最终前哨最终版手机版下载

休闲益智 下载