这个需求如果不会的话还是挺难想出来的,但是掌握了之后会发现它居然如此简单。
仅仅使用了图形视图框架的坐标系转换,以及设置视图的水平滚动条和垂直滚动条即可。
- 先获取指定视图上一个点的坐标,这里用鼠标指向的点代替。
- 获取该点对应的场景坐标 scencePos 。
- 执行缩放。
- 获取 scencePos 对应的新的视图坐标 curPoint 。
- 移动滚动条到 curPoint 的位置。
效果如下:
代码如下:
void PolarView::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));
}
参考:
Qt图形视图框架绕不开的问题 - 坐标系
QGraphicsView 如何实现百度地图按照鼠标点进行放大缩小效果