实现滚轮对画布的缩放(以鼠标位置为锚点)

This commit is contained in:
duanshengchao 2024-08-22 20:21:47 +08:00
parent b4040266dd
commit 88eb1b69dd
4 changed files with 120 additions and 1 deletions

View File

@ -11,8 +11,23 @@ public:
explicit DesignerView(QWidget *parent = 0); explicit DesignerView(QWidget *parent = 0);
virtual ~DesignerView(); 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: private:
void initialize(); void initialize();
//缩放相关
void zoom(const QPointF&, double);
bool zoomLimit(double&);
double getScaleFactor();
private:
bool m_bMousePress;
double m_dZoomVaule;
}; };
#endif #endif

View File

@ -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.right(), sceneRect.top(), sceneRect.right(), sceneRect.bottom());
painter->drawLine(sceneRect.left(), sceneRect.bottom(), 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) void DesignerScene::mousePressEvent(QGraphicsSceneMouseEvent* mouseEvent)

View File

@ -1,8 +1,14 @@
#include "designerView.h" #include "designerView.h"
#include <QMouseEvent>
#define MAX_ZoomValue 50.0
#define MIN_ZoomValue 0.02
DesignerView::DesignerView(QWidget *parent) DesignerView::DesignerView(QWidget *parent)
: QGraphicsView(parent) : QGraphicsView(parent)
{ {
m_bMousePress = false;
m_dZoomVaule = 1.0;
initialize(); initialize();
} }
DesignerView::~DesignerView() DesignerView::~DesignerView()
@ -26,3 +32,96 @@ void DesignerView::initialize()
centerOn(0, 0); 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);
}

View File

@ -1,4 +1,4 @@
#include "util/ScalingSelector.h" #include "util/scalingSelector.h"
#include <QGraphicsSceneMouseEvent> #include <QGraphicsSceneMouseEvent>
#include <QGraphicsView> #include <QGraphicsView>
#include <graphicsItem/graphicsBaseItem.h> #include <graphicsItem/graphicsBaseItem.h>