上篇博文《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; } } |