From ba2fb8211f1fd695033eb753c334a282cb965202 Mon Sep 17 00:00:00 2001 From: baiYue Date: Mon, 1 Jun 2026 16:26:02 +0800 Subject: [PATCH] optimize editor route preview synchronization;add preview zoom --- diagramCavas/CMakeLists.txt | 2 + diagramCavas/include/baseView.h | 41 +++++ diagramCavas/include/designerView.h | 30 +-- diagramCavas/include/diagramEditor/editView.h | 4 +- diagramCavas/source/baseDrawingPanel.cpp | 3 +- diagramCavas/source/baseView.cpp | 171 ++++++++++++++++++ diagramCavas/source/designerView.cpp | 170 +---------------- .../diagramEditorBayDetailSettingDlg.cpp | 4 + .../diagramEditorTransDetailSettingDlg.cpp | 5 + .../source/diagramEditor/editPanel.cpp | 2 +- .../source/diagramEditor/editView.cpp | 2 +- diagramCavas/ui/projectModelSetting.ui | 61 ------- 12 files changed, 235 insertions(+), 260 deletions(-) create mode 100644 diagramCavas/include/baseView.h create mode 100644 diagramCavas/source/baseView.cpp diff --git a/diagramCavas/CMakeLists.txt b/diagramCavas/CMakeLists.txt index eeb9657..da88acf 100644 --- a/diagramCavas/CMakeLists.txt +++ b/diagramCavas/CMakeLists.txt @@ -2,6 +2,7 @@ project(diagramCavas) set(DIAGRAMCAVAS_HEADER_FILES include/baseScene.h + include/baseView.h include/designerScene.h include/designerView.h include/diagramCavas.h @@ -168,6 +169,7 @@ set(DIAGRAMCAVAS_HEADER_FILES set(DIAGRAMCAVAS_SOURCE_FILES source/baseScene.cpp + source/baseView.cpp source/designerScene.cpp source/designerView.cpp source/diagramCavas.cpp diff --git a/diagramCavas/include/baseView.h b/diagramCavas/include/baseView.h new file mode 100644 index 0000000..8651fb4 --- /dev/null +++ b/diagramCavas/include/baseView.h @@ -0,0 +1,41 @@ +#ifndef BASEVIEW_H +#define BASEVIEW_H + +#include + +class BaseView : public QGraphicsView +{ + Q_OBJECT + +public: + explicit BaseView(QWidget *parent = 0); + virtual ~BaseView(); + + virtual void initialize(); + + //视图操作-外部调用 + void zoomIn(); + void zoomOut(); + void zoomFit(); + +protected: + virtual void mousePressEvent(QMouseEvent*) override; + virtual void mouseMoveEvent(QMouseEvent*) override; + virtual void mouseReleaseEvent(QMouseEvent*) override; + virtual void wheelEvent(QWheelEvent*) override; +protected: + //视图操作相关 + void zoom(const QPointF&, double); + bool zoomLimit(double&); + double getScaleFactor(); + void translate(const QPointF&); +signals: + void onScaleChanged(double d); +protected: + bool m_bMousePress; + double m_dScale; + QPointF m_ptLatstMouse_view; //鼠标最后按下在view中的位置 + int m_nLevel; +}; + +#endif diff --git a/diagramCavas/include/designerView.h b/diagramCavas/include/designerView.h index 8adcbb9..84da27b 100644 --- a/diagramCavas/include/designerView.h +++ b/diagramCavas/include/designerView.h @@ -1,9 +1,9 @@ #ifndef DESIGNER_VIEW_H #define DESIGNER_VIEW_H -#include +#include "baseView.h" -class DesignerView : public QGraphicsView +class DesignerView : public BaseView { Q_OBJECT @@ -11,31 +11,7 @@ public: explicit DesignerView(QWidget *parent = 0); virtual ~DesignerView(); - //视图操作-外部调用 - void zoomIn(); - void zoomOut(); - void zoomFit(); - -protected: - //virtual void contextMenuEvent(QContextMenuEvent*) override; - virtual void mousePressEvent(QMouseEvent*) override; - virtual void mouseMoveEvent(QMouseEvent*) override; - virtual void mouseReleaseEvent(QMouseEvent*) override; - virtual void wheelEvent(QWheelEvent*) override; -private: - void initialize(); - //视图操作相关 - void zoom(const QPointF&, double); - bool zoomLimit(double&); - double getScaleFactor(); - void translate(const QPointF&); -signals: - void onScaleChanged(double d); -private: - bool m_bMousePress; - double m_dScale; - QPointF m_ptLatstMouse_view; //鼠标最后按下在view中的位置 - int m_nLevel; + void initialize() override; }; #endif diff --git a/diagramCavas/include/diagramEditor/editView.h b/diagramCavas/include/diagramEditor/editView.h index 7b06b32..4b78fb9 100644 --- a/diagramCavas/include/diagramEditor/editView.h +++ b/diagramCavas/include/diagramEditor/editView.h @@ -1,9 +1,9 @@ #ifndef EDITVIEW_H #define EDITVIEW_H -#include +#include "baseView.h" -class EditView : public QGraphicsView +class EditView : public BaseView { Q_OBJECT public: diff --git a/diagramCavas/source/baseDrawingPanel.cpp b/diagramCavas/source/baseDrawingPanel.cpp index 648cbf4..26993cf 100644 --- a/diagramCavas/source/baseDrawingPanel.cpp +++ b/diagramCavas/source/baseDrawingPanel.cpp @@ -28,10 +28,11 @@ BaseDrawingPanel::BaseDrawingPanel(PowerEntity* pEntity,QWidget *parent,DiagramM m_pSelectorManager = new SelectorManager(_pModel,this); m_pGraphicsScene = new DesignerScene(_pModel,this); //设置场景大小.前两个参数为scene的坐标远点,设置到view的中心点后,无论view如何缩放,secne的坐标原点都不会动,方便后续的位置计算 - m_pGraphicsScene->setSceneRect(0,0, Constants::SCENE_WIDTH*4, Constants::SCENE_HEIGHT*4); + m_pGraphicsScene->setSceneRect(0,0, Constants::SCENE_WIDTH*6, Constants::SCENE_HEIGHT*6); m_pGraphicsScene->setGridVisible(true); m_pGraphicsView = new DesignerView(this); + m_pGraphicsView->initialize(); m_pGraphicsView->setScene(m_pGraphicsScene); m_pGraphicsView->setViewportUpdateMode(QGraphicsView::FullViewportUpdate); m_pGraphicsScene->setView(m_pGraphicsView); diff --git a/diagramCavas/source/baseView.cpp b/diagramCavas/source/baseView.cpp new file mode 100644 index 0000000..59337ef --- /dev/null +++ b/diagramCavas/source/baseView.cpp @@ -0,0 +1,171 @@ +#include "baseView.h" +#include + +#define MAX_ZoomValue 50.0 +#define MIN_ZoomValue 0.02 + +BaseView::BaseView(QWidget *parent) + : QGraphicsView(parent) +{ + m_bMousePress = false; + m_dScale = 1.0; + initialize(); + m_nLevel = 10; + this->setFocusPolicy(Qt::ClickFocus); +} +BaseView::~BaseView() +{ + +} + +void BaseView::initialize() +{ + +} + +void BaseView::mousePressEvent(QMouseEvent* event) +{ + QGraphicsItem* item = scene()->itemAt(mapToScene(event->pos()), transform()); + if (event->button() == Qt::MiddleButton /*&& !item*/) //在空白处按住中键进行拖动 + { + m_bMousePress = true; + setCursor(Qt::ClosedHandCursor); + m_ptLatstMouse_view = event->pos(); + } + else + QGraphicsView::mousePressEvent(event); +} + +void BaseView::mouseMoveEvent(QMouseEvent* event) +{ + if(m_bMousePress) + { + QPointF mouseMoveLength = event->pos() - m_ptLatstMouse_view.toPoint(); + translate(mouseMoveLength); + m_ptLatstMouse_view = event->pos(); + } + else + QGraphicsView::mouseMoveEvent(event); +} + +void BaseView::mouseReleaseEvent(QMouseEvent* event) +{ + if (event->button() == Qt::MiddleButton) //按住中键进行拖动 + { + m_bMousePress = false; + setCursor(Qt::ArrowCursor); + } + else + QGraphicsView::mouseReleaseEvent(event); +} + +void BaseView::wheelEvent(QWheelEvent* event) //滚轮进行放大缩小 +{ + QPointF mousePos = event->position(); + double angleDeltaY = event->angleDelta().y(); + double zoomFactor = qPow(1.0015, angleDeltaY); //可以实现更平滑的缩放 + + zoom(mousePos, zoomFactor); + + //注意不要调用基类的滚轮函数,否则滚轮事件会映射到滚动条操作 + //QGraphicsView::wheelEvent(event); +} + +double BaseView::getScaleFactor() +{ + //QTransform为一个3*3的矩阵,m11和m22元素分别为水平和垂直的缩放值 + return this->transform().m11(); +} + +bool BaseView::zoomLimit(double& value) +{ + m_dScale *= value; + if(m_dScale >= MAX_ZoomValue) + { + m_dScale = MAX_ZoomValue; + value = m_dScale / getScaleFactor(); + } + else if(m_dScale <= MIN_ZoomValue) + { + m_dScale = MIN_ZoomValue; + value = m_dScale / getScaleFactor(); + } + + if(qFabs(value - 1) < 0.01) //缩放因子近似为1 + return true; + + if(value > 1) + m_nLevel +=1; + else + m_nLevel -=1; + + emit onScaleChanged(m_nLevel); + return false; +} + +void BaseView::zoom(const QPointF& mousePos, double zoomFactor) +{ + if(zoomLimit(zoomFactor)) + return; + + /* + * QGraphicsView的默认transformationAnchor(变换锚点)是AnchorViewCenter,也就是中心,此处希望以鼠标指向为变换中心, + * AnchorUnderMouse可以实现,但经尝试没有自己进行移动(translate)效果好,所以先设置成NoAnchor,变换后再设置回来 + */ + ViewportAnchor lastAnchor = this->transformationAnchor(); + setTransformationAnchor(QGraphicsView::NoAnchor); + QPointF targetScenePos = mapToScene(mousePos.toPoint()); + QTransform trans = transform(); + trans.translate(targetScenePos.x(), targetScenePos.y()); + trans.scale(zoomFactor, zoomFactor); + trans.translate(-targetScenePos.x(), -targetScenePos.y()); + setTransform(trans); + setTransformationAnchor(lastAnchor); +} + +void BaseView::zoomIn() +{ + //以view的中心点作为放大中心 + double dWidth_View = viewport()->width(); + double dHeight_View = viewport()->height(); + QPoint pt(dWidth_View * 0.5, dHeight_View * 0.5); + zoom(pt, 1.1); +} + +void BaseView::zoomOut() +{ + //以view的中心点作为缩小中心 + double dWidth_View = viewport()->width(); + double dHeight_View = viewport()->height(); + QPoint pt(dWidth_View * 0.5, dHeight_View * 0.5); + zoom(pt, 0.9); +} + +void BaseView::zoomFit() +{ + resetTransform(); + + double dWidth_View = viewport()->width(); + double dHeight_View = viewport()->height(); + double dWidth_Scene = scene()->sceneRect().width(); + double dHeight_Scene = scene()->sceneRect().height(); + + double dWidthScale = dWidth_View / dWidth_Scene; + double dHeightScale = dHeight_View / dHeight_Scene; + m_dScale = qMin(dWidthScale, dHeightScale); + + QTransform trans = transform(); + trans.scale(m_dScale, m_dScale); + setTransform(trans); + centerOn(0, 0); +} + +void BaseView::translate(const QPointF& delta) +{ + ViewportAnchor lastAnchor = this->transformationAnchor(); + setTransformationAnchor(QGraphicsView::NoAnchor); + QTransform trans = transform(); + trans.translate(delta.x(), delta.y()); + setTransform(trans); + setTransformationAnchor(lastAnchor); +} diff --git a/diagramCavas/source/designerView.cpp b/diagramCavas/source/designerView.cpp index b11dc03..0e71525 100644 --- a/diagramCavas/source/designerView.cpp +++ b/diagramCavas/source/designerView.cpp @@ -1,19 +1,12 @@ #include "designerView.h" -#include "designerScene.h" #include -#define MAX_ZoomValue 50.0 -#define MIN_ZoomValue 0.02 - DesignerView::DesignerView(QWidget *parent) - : QGraphicsView(parent) + : BaseView(parent) { - m_bMousePress = false; - m_dScale = 1.0; - initialize(); - m_nLevel = 10; - this->setFocusPolicy(Qt::ClickFocus); + } + DesignerView::~DesignerView() { @@ -35,160 +28,3 @@ void DesignerView::initialize() centerOn(0, 0); } - -/*void DesignerView::contextMenuEvent(QContextMenuEvent* event) -{ - /*Q_UNUSED(event); - m_bMousePress = false; - QMenu menu; - QAction *removeAction = menu.addAction(QString::fromWCharArray(L"删除")); - menu.exec(QCursor::pos()); -}*/ - -void DesignerView::mousePressEvent(QMouseEvent* event) -{ - QGraphicsItem* item = scene()->itemAt(mapToScene(event->pos()), transform()); - if (event->button() == Qt::MiddleButton /*&& !item*/) //在空白处按住中键进行拖动 - { - m_bMousePress = true; - setCursor(Qt::ClosedHandCursor); - m_ptLatstMouse_view = event->pos(); - } - else - QGraphicsView::mousePressEvent(event); -} - -void DesignerView::mouseMoveEvent(QMouseEvent* event) -{ - if(m_bMousePress) - { - QPointF mouseMoveLength = event->pos() - m_ptLatstMouse_view.toPoint(); - translate(mouseMoveLength); - m_ptLatstMouse_view = event->pos(); - } - else - QGraphicsView::mouseMoveEvent(event); -} - -void DesignerView::mouseReleaseEvent(QMouseEvent* event) -{ - if (event->button() == Qt::MiddleButton) //按住中键进行拖动 - { - m_bMousePress = false; - setCursor(Qt::ArrowCursor); - } - else - QGraphicsView::mouseReleaseEvent(event); -} - -void DesignerView::wheelEvent(QWheelEvent* event) //滚轮进行放大缩小 -{ - QPointF mousePos = event->position(); - double angleDeltaY = event->angleDelta().y(); - double zoomFactor = qPow(1.0015, angleDeltaY); //可以实现更平滑的缩放 - - zoom(mousePos, zoomFactor); - - //注意不要调用基类的滚轮函数,否则滚轮事件会映射到滚动条操作 - //QGraphicsView::wheelEvent(event); -} - -double DesignerView::getScaleFactor() -{ - //QTransform为一个3*3的矩阵,m11和m22元素分别为水平和垂直的缩放值 - return this->transform().m11(); -} - -bool DesignerView::zoomLimit(double& value) -{ - m_dScale *= value; - if(m_dScale >= MAX_ZoomValue) - { - m_dScale = MAX_ZoomValue; - value = m_dScale / getScaleFactor(); - } - else if(m_dScale <= MIN_ZoomValue) - { - m_dScale = MIN_ZoomValue; - value = m_dScale / getScaleFactor(); - } - - if(qFabs(value - 1) < 0.01) //缩放因子近似为1 - return true; - - if(value > 1) - m_nLevel +=1; - else - m_nLevel -=1; - - emit onScaleChanged(m_nLevel); - return false; -} - -void DesignerView::zoom(const QPointF& mousePos, double zoomFactor) -{ - if(zoomLimit(zoomFactor)) - return; - - /* - * QGraphicsView的默认transformationAnchor(变换锚点)是AnchorViewCenter,也就是中心,此处希望以鼠标指向为变换中心, - * AnchorUnderMouse可以实现,但经尝试没有自己进行移动(translate)效果好,所以先设置成NoAnchor,变换后再设置回来 - */ - ViewportAnchor lastAnchor = this->transformationAnchor(); - setTransformationAnchor(QGraphicsView::NoAnchor); - QPointF targetScenePos = mapToScene(mousePos.toPoint()); - QTransform trans = transform(); - trans.translate(targetScenePos.x(), targetScenePos.y()); - trans.scale(zoomFactor, zoomFactor); - trans.translate(-targetScenePos.x(), -targetScenePos.y()); - setTransform(trans); - setTransformationAnchor(lastAnchor); - //emit onScaleChanged(m_nLevel); -} - -void DesignerView::zoomIn() -{ - //以view的中心点作为放大中心 - double dWidth_View = viewport()->width(); - double dHeight_View = viewport()->height(); - QPoint pt(dWidth_View * 0.5, dHeight_View * 0.5); - zoom(pt, 1.1); -} - -void DesignerView::zoomOut() -{ - //以view的中心点作为缩小中心 - double dWidth_View = viewport()->width(); - double dHeight_View = viewport()->height(); - QPoint pt(dWidth_View * 0.5, dHeight_View * 0.5); - zoom(pt, 0.9); -} - -void DesignerView::zoomFit() -{ - resetTransform(); - - double dWidth_View = viewport()->width(); - double dHeight_View = viewport()->height(); - double dWidth_Scene = scene()->sceneRect().width(); - double dHeight_Scene = scene()->sceneRect().height(); - - double dWidthScale = dWidth_View / dWidth_Scene; - double dHeightScale = dHeight_View / dHeight_Scene; - m_dScale = qMin(dWidthScale, dHeightScale); - - QTransform trans = transform(); - trans.scale(m_dScale, m_dScale); - setTransform(trans); - centerOn(0, 0); -} - -void DesignerView::translate(const QPointF& delta) -{ - ViewportAnchor lastAnchor = this->transformationAnchor(); - setTransformationAnchor(QGraphicsView::NoAnchor); - QTransform trans = transform(); - trans.translate(delta.x(), delta.y()); - setTransform(trans); - setTransformationAnchor(lastAnchor); -} diff --git a/diagramCavas/source/diagramEditor/diagramEditorBayDetailSettingDlg.cpp b/diagramCavas/source/diagramEditor/diagramEditorBayDetailSettingDlg.cpp index 36a6179..ee8b360 100644 --- a/diagramCavas/source/diagramEditor/diagramEditorBayDetailSettingDlg.cpp +++ b/diagramCavas/source/diagramEditor/diagramEditorBayDetailSettingDlg.cpp @@ -304,6 +304,7 @@ void DiagramEditorBayDetailSettingDlg::onOkClicked() void DiagramEditorBayDetailSettingDlg::onCancelClicked() { + _pModel->clearCurPreview(); hide(); } @@ -363,6 +364,9 @@ void DiagramEditorBayDetailSettingDlg::onRouteDeleteClicked() } } } + + _pModel->clearCurPreview(); + showPreview(); } void DiagramEditorBayDetailSettingDlg::onRouteRbtnClicked(const QPoint &pos) diff --git a/diagramCavas/source/diagramEditor/diagramEditorTransDetailSettingDlg.cpp b/diagramCavas/source/diagramEditor/diagramEditorTransDetailSettingDlg.cpp index 6b82b10..23da03b 100644 --- a/diagramCavas/source/diagramEditor/diagramEditorTransDetailSettingDlg.cpp +++ b/diagramCavas/source/diagramEditor/diagramEditorTransDetailSettingDlg.cpp @@ -308,6 +308,8 @@ void DiagramEditorTransDetailSettingDlg::onOkClicked() void DiagramEditorTransDetailSettingDlg::onCancelClicked() { + _pModel->clearCurPreview(); + showPreview(); hide(); } @@ -353,6 +355,9 @@ void DiagramEditorTransDetailSettingDlg::onRouteDeleteClicked() } removeRouteUsageFromDevices(lst,sName); _transInfo.mapNeutral.value(n).mapRoute.remove(sName); //同步移除数据 + + _pModel->clearCurPreview(); + showPreview(); } void DiagramEditorTransDetailSettingDlg::onRouteRbtnClicked(const QPoint &pos) diff --git a/diagramCavas/source/diagramEditor/editPanel.cpp b/diagramCavas/source/diagramEditor/editPanel.cpp index c85c33f..186b431 100644 --- a/diagramCavas/source/diagramEditor/editPanel.cpp +++ b/diagramCavas/source/diagramEditor/editPanel.cpp @@ -45,7 +45,7 @@ EditPanel::EditPanel(QWidget *parent) m_pEditScene = new EditScene(this); m_pEditScene->setModel(_pModel); //设置场景大小.前两个参数为scene的坐标远点,设置到view的中心点后,无论view如何缩放,secne的坐标原点都不会动,方便后续的位置计算 - m_pEditScene->setSceneRect(0, 0, Constants::SCENE_WIDTH*4, Constants::SCENE_HEIGHT*4); + m_pEditScene->setSceneRect(0, 0, Constants::SCENE_WIDTH*6, Constants::SCENE_HEIGHT*6); m_pEditView = new EditView(this); m_pEditView->setScene(m_pEditScene); diff --git a/diagramCavas/source/diagramEditor/editView.cpp b/diagramCavas/source/diagramEditor/editView.cpp index e2f9598..3906f2c 100644 --- a/diagramCavas/source/diagramEditor/editView.cpp +++ b/diagramCavas/source/diagramEditor/editView.cpp @@ -2,7 +2,7 @@ EditView::EditView(QWidget *parent) - : QGraphicsView(parent) + : BaseView(parent) { this->setFocusPolicy(Qt::ClickFocus); } diff --git a/diagramCavas/ui/projectModelSetting.ui b/diagramCavas/ui/projectModelSetting.ui index bd318c0..14053b0 100644 --- a/diagramCavas/ui/projectModelSetting.ui +++ b/diagramCavas/ui/projectModelSetting.ui @@ -34,67 +34,6 @@ 0 - - - - - 0 - 0 - - - - - 0 - 22 - - - - QWidget { - background: #2c5282; - color: white; - border: none; -} - -QWidget QLabel { - color: white; - font-size: 12px; - background: transparent; -} - - - - 0 - - - 6 - - - 0 - - - 0 - - - 0 - - - - - - -1 - - - - - - - 工程模配置 - - - - - -