PyQt学习笔记02-drag & drop

Usually, we can drag and drop two things. Data or some graphical objects. If we drag an image from one application to another, we drag and drop binary data. If we drag a tab in Firefox and move it to another place, we drag and drop a graphical component.


dragEnterEvent() ,该函数在用户将一个对象拖(drag)至widget之上时被调用,其参数为QDragEnterEvent类型的指针。请注意下面事件处理函数和事件的区别。

void QWidget::dragEnterEvent(QDragEnterEvent * event)

Inheritance diagram of QDragEnterEvent

class PySide.QtGui. QDragEnterEvent ( pos, actions, data, buttons, modifiers ) ¶
Parameters:
  • actions – PySide.QtCore.Qt.DropActions
  • modifiers – PySide.QtCore.Qt.KeyboardModifiers
  • data – PySide.QtCore.QMimeData
  • pos – PySide.QtCore.QPoint
  • buttons – PySide.QtCore.Qt.MouseButtons


dropEvent() ,该函数在用户将一个对象拽(drop)至widget之上时被调用,参数为QDropEvent类型的指针


默认情况下,QTextEdit这个widget接受来自于其他程序的文本拖拽的;如果用户将一个文件拖拽至其上,它会将文件名插入显示文本。可以调用setAcceptDrops()来允许或禁止接受拖拽。


 QDrag事件类使用QMimeData类来存储与拖拽操作相关的信息, 下面所谓的action是指在拖放操作的过程中,如果从源对象有mimeData,到了目标对象后,是使用什么action带过来,比如,如果是MoveAction的话,那么源对象应该自己删除自己的。如果是CopyAction,源删不删可以自己根据意图处理。


Drag and Drop Actions

In the simplest case, the target of a drag and drop action receives a copy of the data being dragged, and the source decides whether to delete the original. This is described by the CopyAction action. The target may also choose to handle other actions, specifically the MoveAction and LinkAction actions. If the source callsQDrag::exec(), and it returns MoveAction, the source is responsible for deleting any original data if it chooses to do so. 

Overriding Proposed Actions

We may also ignore the proposed action, and perform some other action on the data. To do this, we would call the event object's setDropAction() with the preferred action from Qt::DropAction before calling accept(). This ensures that the replacement drop action is used instead of the proposed action.

For more sophisticated applications, reimplementing dragMoveEvent() and dragLeaveEvent() will let you make certain parts of your widgets sensitive to drop events, and give you more control over drag and drop in your application.



在Qt中可以使用QDrag 来拖动操作Graphics各个元素,以此实现方便的拖动操作。

我们可以从QGraphicsItem 重载 mousePressEvent 来做开始拖动的操作,比如

Cpp代码   收藏代码
  1. void Item::mousePressEvent(QGraphicsSceneMouseEvent *event){  
  2.     Qt::MouseButtons btn = event->buttons();  
  3.     if(btn == Qt::LeftButton){  
  4.   
  5.         QDrag* drag = new QDrag(this->scene());  
  6.   
  7.         QMimeData* data = new QMimeData();  
  8.         drag->setMimeData(data);  
  9.   
  10.         QPixmap pixmap(":image.png");   
  11.         QPainter painter(&pixmap);  
  12.   
  13.         drag->setPixmap(pixmap); //这里设置拖拽时跟随鼠标的图片  
  14.         drag->setHotSpot(QPoint(15,15)); //设置跟随图片的中心点  
  15.   
  16.         drag->exec();   //开始拖拽, 释放拖拽执行下面代码  
  17.         #ifdef Q_WS_WIN     //linux系统中你不能删除drag,删除会由系统自动执行(自己调试得知,可能不正确)  
  18.              delete drag;//注意 上面QMimeData* data这里也会一并删除  
  19.          #endif  
  20.   }  
  21. }  

 这样当我们鼠标按下这个Item时候 拖动就可以开始了

我们有了可以拖的,还必须有去接收这个拖拽的东西,因为只有定义了允许放东西的地方。你才能把东西放里面

于是我们重载另一QGraphicsItem 的dropEvent函数

拖拽接收方代码   收藏代码
  1. void DragReceiverItem::dropEvent(QGraphicsSceneDragDropEvent *event)  
  2. {  
  3.       
  4.     qDebug() << "drop event " ;  
  5.     qDebug() << "pos =  " << event->pos();  
  6.     qDebug() << "scene pos = " << event->scenePos();  
  7.     qDebug() << "screen pos = " << event->screenPos();  
  8.     qDebug() << "mime data = " << event->mimeData();  
  9.       
  10. }  

 可以看到 mimeData也会随着 QGraphicsSceneDragDropEvent传递过来,这样拖拽就可以传递一些我们自己的数据。

还有一点要注意,就是QGraphicsItem必须设置 accpetDrop 为true之后才能触发DropEvent等事件

然后我们还有很多地方可以定制,比如

Cpp代码   收藏代码
  1. void DragReceiverItem::dragEnterEvent(QGraphicsSceneDragDropEvent *event)  
  2. {  
  3.     qDebug() << "拖到 当前Item里面时";  
  4. }  
  5.   
  6. void DragReceiverItem::dragLeaveEvent(QGraphicsSceneDragDropEvent *event)  
  7. {  
  8.     qDebug() << "拖到当前item外面时";  
  9. }  
  10.   
  11. void DragReceiverItem::dragMoveEvent(QGraphicsSceneDragDropEvent *event)  
  12. {  
  13.     qDebug() << "拖到当前item里面的移动时";  
  14. }  
 

综上,我们拖拽操作的拖动方与接收方都定义好了,我们就可以方便的在Qt Graphics中使用拖拽操作了。


你可能感兴趣的:(PyQt学习笔记02-drag & drop)