From 88eb1b69dde5d7d384c78b8aa9fb3f45c61f5102 Mon Sep 17 00:00:00 2001 From: duanshengchao <519970194@qq.com> Date: Thu, 22 Aug 2024 20:21:47 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E6=BB=9A=E8=BD=AE=E5=AF=B9?= =?UTF-8?q?=E7=94=BB=E5=B8=83=E7=9A=84=E7=BC=A9=E6=94=BE(=E4=BB=A5?= =?UTF-8?q?=E9=BC=A0=E6=A0=87=E4=BD=8D=E7=BD=AE=E4=B8=BA=E9=94=9A=E7=82=B9?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/designerView.h | 15 +++++ source/designerScene.cpp | 5 ++ source/designerView.cpp | 99 +++++++++++++++++++++++++++++++++ source/util/scalingSelector.cpp | 2 +- 4 files changed, 120 insertions(+), 1 deletion(-) diff --git a/include/designerView.h b/include/designerView.h index 2e81511..8dc051b 100644 --- a/include/designerView.h +++ b/include/designerView.h @@ -11,8 +11,23 @@ public: explicit DesignerView(QWidget *parent = 0); virtual ~DesignerView(); +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(); + +private: + bool m_bMousePress; + double m_dZoomVaule; }; #endif diff --git a/source/designerScene.cpp b/source/designerScene.cpp index 53899ba..c2873c8 100644 --- a/source/designerScene.cpp +++ b/source/designerScene.cpp @@ -37,6 +37,11 @@ void DesignerScene::drawBackground(QPainter* painter, const QRectF& rect) //补齐最后两条 painter->drawLine(sceneRect.right(), sceneRect.top(), sceneRect.right(), sceneRect.bottom()); painter->drawLine(sceneRect.left(), sceneRect.bottom(), sceneRect.right(), sceneRect.bottom()); + + //原点 + // painter->setPen(Qt::red); + // painter->setBrush(Qt::red); + // painter->drawEllipse(0, 0, 50, 50); } void DesignerScene::mousePressEvent(QGraphicsSceneMouseEvent* mouseEvent) diff --git a/source/designerView.cpp b/source/designerView.cpp index f55598f..32779b5 100644 --- a/source/designerView.cpp +++ b/source/designerView.cpp @@ -1,8 +1,14 @@ #include "designerView.h" +#include + +#define MAX_ZoomValue 50.0 +#define MIN_ZoomValue 0.02 DesignerView::DesignerView(QWidget *parent) : QGraphicsView(parent) { + m_bMousePress = false; + m_dZoomVaule = 1.0; initialize(); } DesignerView::~DesignerView() @@ -26,3 +32,96 @@ void DesignerView::initialize() centerOn(0, 0); } + +bool DesignerView::zoomLimit(double& value) +{ + m_dZoomVaule *= value; + if(m_dZoomVaule >= MAX_ZoomValue) + { + m_dZoomVaule = MAX_ZoomValue; + value = m_dZoomVaule / getScaleFactor(); + } + else if(m_dZoomVaule <= MIN_ZoomValue) + { + m_dZoomVaule = MIN_ZoomValue; + value = m_dZoomVaule / getScaleFactor(); + } + + if(qFabs(value - 1) < 0.01) //缩放因子近似为1 + return true; + + 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); +} + +double DesignerView::getScaleFactor() +{ + //QTransform为一个3*3的矩阵,m11和m22元素分别为水平和垂直的缩放值 + return this->transform().m11(); +} + +void DesignerView::contextMenuEvent(QContextMenuEvent* event) +{ + Q_UNUSED(event); + m_bMousePress = false; +} + +void DesignerView::mousePressEvent(QMouseEvent* event) +{ + if (event->button() == Qt::MiddleButton) //按住中键进行拖动 + { + m_bMousePress = true; + } + else + QGraphicsView::mousePressEvent(event); +} + +void DesignerView::mouseMoveEvent(QMouseEvent* event) +{ + if(m_bMousePress) + { + + } + else + QGraphicsView::mouseMoveEvent(event); +} + +void DesignerView::mouseReleaseEvent(QMouseEvent* event) +{ + if (event->button() == Qt::MiddleButton) //按住中键进行拖动 + { + m_bMousePress = false; + } + 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); +} diff --git a/source/util/scalingSelector.cpp b/source/util/scalingSelector.cpp index f742374..a9110b7 100644 --- a/source/util/scalingSelector.cpp +++ b/source/util/scalingSelector.cpp @@ -1,4 +1,4 @@ -#include "util/ScalingSelector.h" +#include "util/scalingSelector.h" #include #include #include