QGraphicsView 如何实现百度地图按照鼠标点进行放大缩小效果
来源:互联网 发布:淘宝开店 pdf 编辑:程序博客网 时间:2024/06/04 22:44
一、简述
前段时间用了QGraphicsView做了一些工作,然而如何实现QGraphicsView的放大缩小的效果也很简单,直接重写QGraphicsView的wheelEvent事件即可,上一篇文章中也提到了,但是仅仅通过以下代码实现放大缩小的效果并不是很完美。
虽然达到了放大缩小的效果,但是并没有像百度地图一样能够按照鼠标某一点进行缩放,仅靠以下代码对view进行缩放会导致view上的item在放大缩小的过程中跑偏了。
void CustomView::wheelEvent(QWheelEvent *event){ // 当前放缩倍数; qreal scaleFactor = this->matrix().m11(); int wheelDeltaValue = event->delta(); // 向上滚动,放大; if (wheelDeltaValue > 0) { this->scale(1.2, 1.2); } // 向下滚动,缩小; else { this->scale(1.0 / 1.2, 1.0 / 1.2); }}
我们看一下仅靠以上代码实现的放大缩小的效果。
从下图中我们看到把图中小矩形放到屏幕中央进行放大缩小时,效果还是可以的,但是当我们吧小矩形拖到屏幕靠左位置时(或者靠右,只要不是中央位置),我们发现放大所需时小矩形位置偏移较为严重,为了就解决这个问题,闭关修炼了三天,终于解决了。期间各种百度,看助手文档,后来有位小伙伴推荐了一篇文章用MFC实现了图片按照鼠标点进行放大缩小效果,虽然达到了类似的效果,但是和QGraphicsView的原理不一样。那篇文章中通过放大后重新计算图片的位置,然后在对应位置进行重绘。
最后的最后,在QGraphicsView的源码中找到了方法的思路。
我们再看一下百度地图放大缩小的效果(因为受到了图片大小的限制,就截了一小块)。
大家可以看到鼠标分别放到两个绿色矩形区域进行放大缩小的效果,可以看到都是按照鼠标点进行缩放的。
二、代码之路
好了,上面说明了问题,下面就开始针对这个问题进行解决。话不多说,直接上代码。
void CustomView::wheelEvent(QWheelEvent *event){ // 获取当前鼠标相对于view的位置; QPointF cursorPoint = event->pos(); // 获取当前鼠标相对于scene的位置; QPointF scenePos = this->mapToScene(QPoint(cursorPoint.x(), cursorPoint.y())); // 获取view的宽高; qreal viewWidth = this->viewport()->width(); qreal viewHeight = this->viewport()->height(); // 获取当前鼠标位置相当于view大小的横纵比例; qreal hScale = cursorPoint.x() / viewWidth; qreal vScale = cursorPoint.y() / viewHeight; // 当前放缩倍数; qreal scaleFactor = this->matrix().m11(); int wheelDeltaValue = event->delta(); // 向上滚动,放大; if (wheelDeltaValue > 0) { this->scale(1.2, 1.2); } // 向下滚动,缩小; else { this->scale(1.0 / 1.2, 1.0 / 1.2); } // 将scene坐标转换为放大缩小后的坐标; QPointF viewPoint = this->matrix().map(scenePos); // 通过滚动条控制view放大缩小后的展示scene的位置; horizontalScrollBar()->setValue(int(viewPoint.x() - viewWidth * hScale)); verticalScrollBar()->setValue(int(viewPoint.y() - viewHeight * vScale));}
通过上面的代码即可实现QGraphicsView按照鼠标点进行放大缩小的效果。
我们看一下效果,图一中我分别将将小矩形拖到屏幕的上、下、左、右四个方位,我们发现都是按照鼠标点进行了放缩(gif图录制软件在拖到小矩形时生成的图片有点阴影,大家可以忽略)。
图二中,分别将鼠标放置在屏幕的四角,我们可以看到很明确的效果。
图一
图二
附上一张效果图(可能需要放大网页看,相对清楚一点)
下面是QGraphicsView::centerOn(const QPointF &pos)方法的源码。以上代码也是参考了这个方法后得到的结果。这个方法也就是通过滑动滚动条的方法将所给的点(该点是相对于scene的)放置在view 的中央位置。而我们想要实现按照鼠标点进行放大缩小效果,只需要计算当前鼠标位置相对于view大小的比例,centerOn方法中是 1/2 ,我们只要替换为相对应的比例即可。
/*! Scrolls the contents of the viewport to ensure that the scene coordinate \a pos, is centered in the view. Because \a pos is a floating point coordinate, and the scroll bars operate on integer coordinates, the centering is only an approximation. \note If the item is close to or outside the border, it will be visible in the view, but not centered. \sa ensureVisible()*/void QGraphicsView::centerOn(const QPointF &pos){ Q_D(QGraphicsView); qreal width = viewport()->width(); qreal height = viewport()->height(); QPointF viewPoint = d->matrix.map(pos); QPointF oldCenterPoint = pos; if (!d->leftIndent) { if (isRightToLeft()) { qint64 horizontal = 0; horizontal += horizontalScrollBar()->minimum(); horizontal += horizontalScrollBar()->maximum(); horizontal -= int(viewPoint.x() - width / 2.0); horizontalScrollBar()->setValue(horizontal); } else { horizontalScrollBar()->setValue(int(viewPoint.x() - width / 2.0)); } } if (!d->topIndent) verticalScrollBar()->setValue(int(viewPoint.y() - height / 2.0)); d->lastCenterPoint = oldCenterPoint;}
- QGraphicsView 如何实现百度地图按照鼠标点进行放大缩小效果
- 使用鼠标滚轮实现放大缩小地图
- 鼠标滚轮实现地图放大缩小 并以滚轮点为中心点
- QGraphicsView放大和缩小下鼠标位置使用鼠标滚轮
- 鼠标滚轮放大缩小地图
- 新版百度地图Android SDK 如何调用放大缩小功能
- 鼠标滚轮实现放大缩小
- 百度地图显示/隐藏放大缩小按钮
- java JFrame去掉标题栏后如何实现鼠标移动到边框可以进行拖拉以放大缩小
- CSS实现鼠标覆盖地图省名放大效果
- 鼠标滚动实现图片放大缩小[转]
- unity 实现了鼠标滚动放大和缩小物体暨拉近拉远相机的效果
- 基于jquery实现一张图片点击鼠标放大再点缩小
- google map放大缩小地图去除 ctrl+,直接用鼠标放大缩小
- CSS、jQuery实现放大缩小动画效果
- android 控件放大缩小效果实现
- unity shader 实现自由放大缩小效果
- 如何使QGraphicsItem不随QGraphicsView放大缩小而改变大小
- 和为s的两个数字VS和为s的连续正数序列
- 51nod 1424 零树(树形dp)
- V-Parenthesis 前缀+ZKW线段树或RMQ
- 数组、List和ArrayList的区别
- Rikka with Graph(HDU 6090)
- QGraphicsView 如何实现百度地图按照鼠标点进行放大缩小效果
- 在VS2013环境下使用EF框架与Sqlite(二)
- SQL Server 检测到基于一致性的逻辑 I-O 错误 pageid 不正确
- 1015. 德才论
- 在java web项目中调用c++的dll程序简单案例
- python 中文路径带来的错误和解决
- select选择不同option,局部切换div或者其他布局
- 大话数据结构 -绪论
- 第九章 JSR303验证-跟赵大笨笨学SpringMVC