181 lines
5.1 KiB
C++
181 lines
5.1 KiB
C++
|
|
#include "designerView.h"
|
|||
|
|
#include <QMouseEvent>
|
|||
|
|
|
|||
|
|
#define MAX_ZoomValue 50.0
|
|||
|
|
#define MIN_ZoomValue 0.02
|
|||
|
|
|
|||
|
|
DesignerView::DesignerView(QWidget *parent)
|
|||
|
|
: QGraphicsView(parent)
|
|||
|
|
{
|
|||
|
|
m_bMousePress = false;
|
|||
|
|
m_dScale = 1.0;
|
|||
|
|
initialize();
|
|||
|
|
}
|
|||
|
|
DesignerView::~DesignerView()
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void DesignerView::initialize()
|
|||
|
|
{
|
|||
|
|
//去掉QGraphicsView自带滚动条
|
|||
|
|
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
|||
|
|
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
|||
|
|
//设置背景
|
|||
|
|
setStyleSheet("background-image: url(:/images/checkerboard.png);\
|
|||
|
|
padding: 0px; \
|
|||
|
|
border: 0px;");
|
|||
|
|
//打开反锯齿
|
|||
|
|
setRenderHint(QPainter::Antialiasing);
|
|||
|
|
setMouseTracking(true);
|
|||
|
|
//setDragMode(QGraphicsView::RubberBandDrag); //将控制交给selector
|
|||
|
|
|
|||
|
|
centerOn(0, 0);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void DesignerView::contextMenuEvent(QContextMenuEvent* event)
|
|||
|
|
{
|
|||
|
|
Q_UNUSED(event);
|
|||
|
|
m_bMousePress = false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
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;
|
|||
|
|
|
|||
|
|
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);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
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);
|
|||
|
|
}
|