上篇博文《QT QGraphicsProxyWidget对象可选择或移动的一些tricks》介绍了实现QT QGraphicsProxyWidget对象可选择或移动的一些小的第三方技巧,但是在实际的项目中一般不那么做。
之前自己学习QGraphicsView研究的还不是很深入,在scene中加入大量的item后,scene框架提供了注入items()、itemAt()等遍历管理其中item的一些操作。
思路:通过对scene中进行鼠标点选获取选择的item(本文主要说的是QGraphicsProxyWidget对象),然后跟随鼠标拖动事件设置其在scene中的位置,终于开阔了思路!
先看一下效果图:
一个QGraphicsProxyWidget嵌入了一个QPushButton;另一个QGraphicsProxyWidget嵌入了一个QCombobox
相关代码如下:
C++ Code
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
class GraphicsScene : public QGraphicsScene
{ Q_OBJECT public: GraphicsScene(); protected: void mousePressEvent(QGraphicsSceneMouseEvent *event); void mouseMoveEvent(QGraphicsSceneMouseEvent *event); void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); private: QGraphicsItem *m_pItemSelected; // 鼠标单选item QPoint m_shiftOrg; // 鼠标点选item中位置相对于item原点的偏移量 }; // 鼠标按下获取当前单选中的QGraphicsProxyWidget图元对象 void GraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *event) { qDebug() << "scene mouse press"; QGraphicsScene::mousePressEvent(event); if (event->button() == Qt::LeftButton) { // 检测光标下是否有 item m_pItemSelected = nullptr; foreach (QGraphicsItem *item, items(event->scenePos())) { if (item->type() == QGraphicsProxyWidget::Type) // 代理Widget { QGraphicsProxyWidget *proxyWidget = qgraphicsitem_cast<QGraphicsProxyWidget *>(item); QPointF point = proxyWidget->mapToScene(QPointF(0.0, 0.0)); // 图元左上角在scene中的位置 qDebug() << point.x(); qDebug() << point.y(); // 当前点击图元点在scene中的位置 qDebug() << event->scenePos().x(); qDebug() << event->scenePos().y(); m_shiftOrg.setX(event->scenePos().x() - point.x()); m_shiftOrg.setY(event->scenePos().y() - point.y()); m_pItemSelected = item; break; } } } } // 鼠标移动过程中跟随位置改变 void GraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { qDebug() << "scene mouse move"; QGraphicsScene::mouseMoveEvent(event); if(m_pItemSelected != nullptr) { m_pItemSelected->setPos(event->scenePos().x() - m_shiftOrg.x(), event->scenePos().y() - m_shiftOrg.y()); } } // 鼠标释放后作为最后的位置 void GraphicsScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { qDebug() << "scene mouse release"; QGraphicsScene::mouseReleaseEvent(event); if(m_pItemSelected != nullptr) { m_pItemSelected->setPos(event->scenePos().x() - m_shiftOrg.x(), event->scenePos().y() - m_shiftOrg.y()); m_pItemSelected = nullptr; } } |