#include "designerView.h" #include #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); }