在《qt4精彩实例分析》中最后一章介绍了关于拖曳类的例程,但是有些不好理解。下面是我个人看完后的一些总结:
首先,关于拖曳有一个拖曳的对象,还要有一个盛拖曳对象的容器。所以至少要有两个类。然后,要在拖曳对象中实现两个事件:void mousePressEvent(QMouseEvent *);
void mouseMoveEvent(QMouseEvent *);在这两个事件中,分别对拖曳对象做相应的处理。事件处理中,有这么几个任务:
1.一般是要记录对象拖曳的位置,对象本身的属性信息。这个过程要可能使用的类QByteArray,QDataStream,QMimeData;
eg:QByteArray data;QDataStream stream(&data,QIODevice::WriteOnly);stream << pix << QPoint(e->pos()-rect().topLeft());QMimeData *mimeData = new QMimeData;mimeData->setData("Drag-Icon",data);2.使用QDrag,使用创建的拖曳对象能够产生拖曳事件。
eg:QDrag *drag = new QDrag(this);drag->setMimeData(mimeData);drag->setHotSpot(QPoint(e->pos() - rect().topLeft()));drag->setPixmap(pix);Qt::DropAction dropAction = drag->start(Qt::CopyAction | Qt::MoveAction);//这是关键语句3.处理拖曳时,拖曳对象原位置的显示问题hide();Qt::DropAction dropAction = drag->start(Qt::CopyAction | Qt::MoveAction);if (dropAction == Qt::MoveAction)close();elseshow();在拖曳时一般要隐匿原来位置的对象,所以先要调用hide();然后根据拖曳容器返回的拖曳动作,决定是接着隐匿还是将原来位置的图像显示出来。例如如果去掉if后面的语句,会造成原位置的对象不管怎么样,都不能显示在原来的位置。接着就是有关于盛放拖曳对象的容器它一般要实现这么三个事件: void dragEnterEvent(QDragEnterEvent *);void dragMoveEvent(QDragMoveEvent *);void dropEvent(QDropEvent *);一个是当有新的拖曳对象进入容器时,一个是当容器内有拖曳对象移动时,一个是当拖曳对象到新位置时鼠标停下或松开时。按照《qt4精彩实例分析》中的处理前两个事件只是简单的返回给拖曳类一个拖曳动作,这样好让拖曳对象知道原位置的对象要不要再显示。eg:void DragWidget::dragEnterEvent(QDragEnterEvent * e){
if (e->mimeData()->hasFormat("Drag-Icon")){if(children().contains(e->source())){e->setDropAction(Qt::MoveAction);e->accept();}elsee->acceptProposedAction();}}
但在dropEvent(QDropEvent *)函数中它比上面的函数多了一个任务,就是把拖曳对象在新位置中显示出来。借助于QDropEvent 类的实例携带的参数可以轻松完成这个任务eg: void DragWidget::dropEvent(QDropEvent * e){
if (e->mimeData()->hasFormat("Drag-Icon")){QByteArray data = e->mimeData()->data("Drag-Icon");QDataStream stream(&data,QIODevice::ReadOnly);QPixmap pix;QPoint offset;stream >> pix >> offset;
DragIcon *icon = new DragIcon(pix,this);icon->move(e->pos() - offset);icon->show();
if (children().contains(e->source())){e->setDropAction(Qt::MoveAction);e->accept();}elsee->acceptProposedAction();}elsee->ignore();}
以上是我的一些粗浅直观的认识,希望以后可以更深入更详细地了解qt的拖曳类。