因为编辑器需要在不同的控件之间支持拖拽操作,所以对Qt的拖拽研究了一下.
这里实现一种比较简单的拖拽方案
1.拖拽方控件
拖拽需要支持拖拽的控件开启拖拽功能,调用函数
2 | setDragDropMode(QAbstractItemView::DragOnly); |
其中拖拽模式可查具体的API, 这里设置此空间之支持向外拖拽功能(即只能从此控件向别的控件拖拽操作,而不支持别的控件向此控件拖拽)
然后需要复写startDrag(Qt::DropActions supportedActions)函数来执行开始拖拽时的一些操作.
01 | void DragedListWidget::startDrag(Qt::DropActions supportedActions) |
03 | QListWidgetItem *item = currentItem(); |
05 | QMimeData *mimeData = new QMimeData; |
06 | mimeData->setText(currentItem()->text()); |
08 | mimeData->setProperty( "TYPE" , QVariant( "MODELS" )); |
09 | mimeData->setProperty( "MODEL_TYPE" , QVariant(mType.c_str())); |
11 | QDrag *drag = new QDrag( this ); |
12 | drag->setMimeData(mimeData); |
13 | drag->exec(Qt::MoveAction); |
这里QListWidget支持向外拖拽的功能,其中QMimeData用来再拖拽控件和接受拖拽控件间传输数据,这里我把QListWidgetItem的文本内容作为传输内容发送.并设置了一些限定的属性操作setProperty(这样接受拖拽的控件就可以只接受此控件拖拽来的内容了)构造QDrag对象,并执行拖拽操作.
2.接受拖拽方控件
有几个函数需要复写.
//当拖拽后进入接收拖拽的控件时触发
1.dragEnterEvent(QDragEnterEvent *event)
//当拖拽(没有释放鼠标时)离开接收拖拽的控件时触发
2.dragLeaveEvent(QDragLeaveEvent *event)
//拖拽状态下在接收拖拽的控件内移动鼠标时触发
3.dragMoveEvent(QDragMoveEvent *event)
//拖拽状态下释放鼠标时触发
4.dropEvent(QDropEvent *event)
这里主要针对dragEnterEvent来说明
01 | void OgreWidget::dragEnterEvent(QDragEnterEvent *event) |
04 | const QMimeData *data = event->mimeData(); |
05 | QVariant type = data->property( "TYPE" ); |
06 | if (!mKeyDown && type == QVariant( "MODELS" )) |
08 | QVariant type = data->property( "MODEL_TYPE" ); |
首先从传入的QDragEnterEvent 获取接收到的QMimiData,之后判断这次拖拽是否是需要的拖拽操作, 如果是则event->accept();表明接收此次拖拽事件, 如果不是则调用event->ignore(); 丢弃此次拖拽操作.
只有调用event->accept();之后dragLeaveEvent(QDragLeaveEvent *event), dragMoveEvent(QDragMoveEvent *event), dropEvent(QDropEvent *event)才会在之后触发, 如果是event->ignore(); 则均不触发.