如何在调整大小期间保持相同的场景部分?
Posted
技术标签:
【中文标题】如何在调整大小期间保持相同的场景部分?【英文标题】:How to keep the same scene portion in view during resize? 【发布时间】:2014-08-14 08:06:13 【问题描述】:我正在使用QGraphicsView
来显示函数图之类的东西。 QGraphicsView
在调整大小期间保持其变换,因此场景的可见部分会发生变化。
我需要在调整大小期间保持视图完全相同 - 不必保持纵横比,因为我允许在 X 轴和 Y 轴上独立缩放。
这不起作用:
void resizeEvent(QResizeEvent *event) override
QRectF rect = mapToScene(this->viewport()->rect()).boundingRect();
QGraphicsView::resizeEvent(event);
fitInView(rect);
问题在于获得正确的视图矩形。此解决方案在调整大小时缩小。
有什么简单的方法可以实现吗?
【问题讨论】:
【参考方案1】:我遇到了完全相同的问题。当视图大小发生变化时,您需要手动scale
视图,并恢复旧的中心点。在python中:
def resizeEvent(self, event):
w_ratio = self.rect().width() / event.oldSize().width()
h_ratio = self.rect().height() / event.oldSize().height()
self.scale(w_ratio, h_ratio)
self.centerOn(self.old_center)
您显然需要更早地设置self.old_center
,例如在showEvent()
。如果用户可以翻译视图,您还需要在mouseReleaseEvent()
中更新self.old_center
。
def showEvent(self, event):
self.old_center = self.mapToScene(self.rect().center())
def mouseReleaseEvent(self, event):
super(MyView, self).mouseReleaseEvent(event)
self.old_center = self.mapToScene(self.rect().center())
【讨论】:
【参考方案2】:创建继承自QGraphicsView
的自定义类后,您应该在自定义QGraphicsView
中重新实现resizeEvent( QResizeEvent *event )
,例如:
void MyView::resizeEvent(QResizeEvent *event)
QRectF rect = this->scene()->itemsBoundingRect();
fitInView(rect);
QGraphicsView::resizeEvent(event);
这样视图将始终显示整个场景。 IE。如果改变了窗口大小并且调整了 graphicsView 的大小,场景就会被缩放,你可以适当地看到一切。
【讨论】:
这与我的问题中的代码几乎相同(因此它不起作用)。 不一样。你不要使用Qt::KeepAspectRatio
参数,同样QGraphicsView::resizeEvent(event);
应该在函数结束时调用。
我不需要保持纵横比 - 正如我在问题中所写的那样,我允许每个轴上的独立比例。我最后一次打电话给fitInView()
,因为您需要先调整大小,然后将前一个视图矩形调整到调整大小的视口。顺便说一句,我尝试了您的解决方案。
@Johny 您可以使用QGraphicsScene::itemsBoundingRect
计算并返回场景中所有项目的边界矩形。此外,如果您不想保持纵横比,请忽略Qt::KeepAspectRatio
。我已经更新了答案。
这与我想要的不同 - 这会改变视图。如果我放大了视图(以研究一些细节),这将再次缩小调整大小。【参考方案3】:
在fitInView
的视图中保持这个视图可视化的场景矩形怎么样?
void resizeEvent(QResizeEvent *event) override
QGraphicsView::resizeEvent(event);
fitInView(this->sceneRect());
【讨论】:
我相信这将使整个场景可见,而不是保留场景的当前显示部分。【参考方案4】:我意识到这已经很老了,但我遇到了同样的挑战并找到了一个行之有效的解决方案。
我认为问题在于在调整大小事件中,正在获取视口坐标(映射到场景)。在这种情况下,视口已经改变(因此显示的场景),然后调用 fitInView
并稍微更新了一些场景坐标,因此显示场景实际上发生了变化。这变成了类似级联的效果。
我们想要做的是在调整大小事件期间始终将 same 场景矩形传递给fitInView
。当我第一次加载图像时,我可以通过在本地存储场景坐标来实现这一点,然后在任何时候显示的场景发生变化(平移/缩放/重置视图等)。然后当调用调整大小事件时,我们总是传递相同的场景坐标,而不会陷入那个变化循环。
【讨论】:
以上是关于如何在调整大小期间保持相同的场景部分?的主要内容,如果未能解决你的问题,请参考以下文章