一、简述

前段时间用了QGraphicsView做了一些工作,然而如何实现QGraphicsView的放大缩小的效果也很简单,直接重写QGraphicsViewwheelEvent事件即可,上一篇文章中也提到了,但是仅仅通过以下代码实现放大缩小的效果并不是很完美。

虽然达到了放大缩小的效果,但是并没有像百度地图一样能够按照鼠标某一点进行缩放,仅靠以下代码对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 scenecoordinate \a pos, is centered in the view.Because \a pos is a floating point coordinate, and the scroll bars operateon integer coordinates, the centering is only an approximation.\note If the item is close to or outside the border, it will be visiblein 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 如何实现百度地图按照鼠标点进行放大缩小效果相关推荐

  1. 百度地图之鼠标绘制工具条库(开源库)

    百度地图开发常用网站 1.百度地图开放平台 http://lbsyun.baidu.com/ 2.百度地图 Javascript API JavaScript API v3.0 http://lbsy ...

  2. 百度地图添加自定义图标标注以及自定义动画效果

    百度地图添加自定义图标标注以及自定义动画效果 1.添加自定义图标标注 2.添加自定义动画效果 2.1.标注对象marker的构成 2.2.自定义动画效果实现过程 2.3.最终实现效果 上次写的是添加自 ...

  3. python字体大小快捷键_PyCharm(2019.1版本)用鼠标滚轮控制放大缩小字体

    今天准备使用pycharm来编写scrapy爬虫,结果发现字体很小,习惯性用Ctrl+鼠标滚轮来控制字体大小,发现它竟然不听使唤,才想起来PyCharm是新安装的一直没用,赶紧来设置一番吧. 使用过p ...

  4. pycharm编辑器如何用鼠标滚轮随时放大缩小代码

    pycharm编辑器如何用鼠标滚轮随时放大缩小代码 我们用pycharm的时候发现不能快捷的像其他编辑器那样用鼠标滚轮随时放大缩小代码,这是因为你还没有设置,下面我们就来设置一下. 1.放大代码设置 ...

  5. Unity 在zSpace上使用鼠标控制相机旋转和鼠标指引式放大缩小,在触屏上手势位置为中心放大缩小

    在zSpace上使用鼠标控制相机旋转和鼠标指引式放大缩小,在触屏上手势位置为中心放大缩小 鼠标和触屏的操作 下面展示一些 内联代码片. using System; using System.Colle ...

  6. vue项目引入百度地图BMapGL鼠标绘制和BMap辅助工具

    目录 引言 1.引用百度地图 2.在项目中使用百度地图 2-1.页面结构部分 2-2.js逻辑部分 3-1.页面结构部分 Vue.js 是一个用于构建用户界面的渐进式 JavaScript 框架.它旨 ...

  7. 百度地图实现鼠标绘制多边形并获取所有点坐标

    百度地图开放平台http://lbsyun.baidu.com/ 这里使用的是Javascript API http://lbsyun.baidu.com/index.php?title=jspopu ...

  8. 百度地图标点鼠标样式更改

    需求:修改百度地图红点悬停鼠标样式,有链接的鼠标悬停显示为pointer点击跳转,没有链接的红点悬停后显示鼠标默认样式. 分析1: 核心对象分析,找到红点对象 API查询红点对象控制鼠标样式的方法 百 ...

  9. html中实现鼠标悬停放大,如何实现鼠标悬停图片放大的效果。

    在网页上我们经常看到鼠标悬停在一个图片上,这张图片会慢慢的放大,感觉是像放大镜放大的效果,当鼠标移开的时候,图片有恢复原来的样子,今天就实现这种效果. 实现原理以思路: 1,首先这是一张图片在悬停时放 ...

  10. 鼠标滚动导航放大缩小

    进入页面的样式 鼠标向下的样式 滚轮向上还是可以变大,直接上代码, <!DOCTYPE html> <html lang="zh-CN"> <head ...

最新文章

  1. html滑动逐渐覆盖效果,创意jQuery和CSS3滑动覆盖响应式幻灯片特效
  2. 普通粒子群算法和优化方法
  3. poj 2251 Dungeon Master (三维bfs)
  4. akka和rabbitmq_Akka Notes –演员记录和测试
  5. jacascript AJAX 学习
  6. python写的软件怎么逆向_python逆向工程:通过代码生成类图
  7. IOS学习笔记06---C语言函数
  8. [转]Spring注解-@Configuration注解、@Bean注解以及配置自动扫描、bean作用域
  9. QList、QVector、QMap容器类
  10. 全面分析男性护肤三大误区 - 生活至上,美容至尚!
  11. (转)[Unity3D]UI方案及制作细节(NGUI/EZGUI/原生UI系统) 内附unused-assets清除实例
  12. 进程管理——PV操作
  13. 那些年,我们信了课本里的那些鬼话
  14. Xenserver命令大全
  15. adobe reader XI打开pdf崩溃修复2020.05
  16. Python绘制美国队长盾牌
  17. MATLAB中如何作随时间变化图
  18. 物联网数据卡系统源码——物联网的主要应用领域
  19. 浅谈程序员的英语学习 - 风口上的猪 - 博客园
  20. 大数据项目(基于spark)--新冠疫情防控指挥作战平台项目

热门文章

  1. lightoj1234——调和级数+欧拉常数
  2. 利用matlab求解常数e,利用matlab软件求解常数e和欧拉常数γ.docx
  3. 怎样为Windows7系统设置快速启动栏
  4. 在wine里面播放视频和音乐之WMP
  5. 2021年人工智能五大趋势预测
  6. 数学与应用数学考研计算机方向,数学专业考研方向解析:应用数学
  7. 如何使用python刷博客浏览量---第二种方法
  8. 关于 2021 年度「博客之星」评选刷票行为处罚通知
  9. linux下查看网卡vid,Linux下查看USB设备的VID、PID命令
  10. iPhone密码管理