1、setAcceptDrops(true);
这个设置后,并不是能拖动,而是可以接受dropEvent事件,也就是能响应到拖拽时的放下事件,不设置该属性,则视为该Item不能Drop。 拖拽由下面的 mouseMoveEvent 中的QDrag实现
2、mouseMoveEvent
void GQIGraphicsItem::mouseMoveEvent(QGraphicsSceneMouseEvent * event)
{
if (!m_bCanDrag)
{
return;
}
if (event->buttons() & Qt::LeftButton)
{
//if (QLineF(m_oDragStartPt, event->buttonDownScreenPos(Qt::LeftButton))
// .length() < QApplication::startDragDistance()) {
// return;
//}
if (!isContainsScenePos(event->scenePos()))
{
return;
}
// 添加 QDrag 和 QMimeData 后,可以触发 dragEnterEvent
QDrag *drag = new QDrag((QObject*)event->widget());
QMimeData *mime = new QMimeData;
mime->setData(QString(QMetaType::typeName(QMetaType::Int)), QString("%1").arg(m_nID).toLatin1());
drag->setMimeData(mime);
drag->setHotSpot(mapFromScene(event->scenePos()).toPoint());
// 设置拖动时的鼠标跟随
QPixmap oPixMap(boundingRect().width() * scale(), boundingRect().height() * scale());
QPainter painter(&oPixMap);
paint(&painter);
drag->setPixmap(oPixMap);
drag->exec(Qt::MoveAction);
}
}
<1> 判断是否左键点击 event->buttons() & Qt::LeftButton ,切记是 & 而不是 ==
<2> QDrag,QMimeData一定要有,否则触发不了拖拽事件。QMimeData会将拖拽时的信息,传递给其他事件
<3> 拖拽时跟随鼠标动的不是本身Item,不用在dragMoveEvent事件中处理本体移动。
只需要给QDrag设置Image或者Pixmap即可,对,没错,跟随鼠标动的只是个图片
3、boundingRect
该设置是根据自己本身的局部坐标系作为参考设置的
QRectF GQIGraphicsItem::boundingRect() const
{
return QRectF(0, 0, c_nItemWidth, c_nItemHeight);
}
4、dragEnterEvent
一定要给放下位置的Item设置setAccepted(true),否则后面的事件dropEvent接收不到
void GQIGraphicsItem::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
{
const QMimeData *mime = event->mimeData();
int nId = mime->data(QMetaType::typeName(QMetaType::Int)).toInt();
if(nId == m_nID)
{
event->setAccepted(false);
}
else
{
event->setAccepted(true);
}
}