如何在调整大小时保持相同的场景部分可见?

3

我正在使用QGraphicsView来展示类似函数图像的东西。在调整大小时,QGraphicsView会保持其变换,因此场景的可见部分会改变。

我需要在调整大小期间完全保持视图不变 - 不必保持纵横比,因为我允许在X和Y轴上独立缩放。

这个方法不起作用:

void resizeEvent(QResizeEvent *event) override
{
    QRectF rect = mapToScene(this->viewport()->rect()).boundingRect();
    QGraphicsView::resizeEvent(event);
    fitInView(rect);
}

问题在于如何获得正确的视图矩形。此解决方案可在调整大小时缩小比例。
有没有一种简单的方法来实现这个?
4个回答

1

我曾遇到同样的问题。当视图大小发生变化时,您需要手动缩放视图,并恢复旧的中心点。在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())

0

那么在使用fitInView的视图中,保持此视图可视化的场景矩形如何处理?

void resizeEvent(QResizeEvent *event) override
{
    QGraphicsView::resizeEvent(event);
    fitInView(this->sceneRect());
}

我相信这将使整个场景可见,而不是保持当前显示的部分场景。 - RoHS4U

0

我知道这篇文章已经很老了,但是我遇到了同样的问题并找到了一个解决方案。

我认为问题在于在调整大小事件中获取视口坐标(映射到场景)。在这种情况下,视口已经改变(因此显示的场景也改变了),然后会使用一些稍微更新的场景坐标调用fitInView,从而实际上改变了显示场景。这就变成了一个级联效应。

我们想要做的是始终在调整大小事件期间向fitInView传递相同的场景矩形。我能够通过在首次加载图像时以及每次显示场景更改(平移/缩放/重置视图等)时本地存储场景坐标来实现这一点。然后当调整大小事件被调用时,我们总是传递相同的场景坐标,并且不会被困在那个变化循环中。


0

在创建继承自QGraphicsView的自定义类后,您应该重新实现自定义QGraphicsView中的resizeEvent(QResizeEvent * event)方法:

void MyView::resizeEvent(QResizeEvent *event)
{

    QRectF rect = this->scene()->itemsBoundingRect();
    fitInView(rect);

    QGraphicsView::resizeEvent(event);
}

这样,视图将始终显示整个场景。即,如果窗口大小发生变化并且图形视图被调整大小,场景会被缩放,您可以适当地看到所有内容。

这几乎是我在问题中提到的相同代码(所以它不起作用)。 - Johny
不一样了。您没有使用 Qt::KeepAspectRatio 参数,另外应该在函数末尾调用 QGraphicsView::resizeEvent(event); - Nejat
我不需要保持纵横比 - 正如我在问题中所述,我允许每个轴独立缩放。我上一次调用了 fitInView(),因为您需要先调整大小,然后将前一个视图矩形适应调整大小的视口。顺便说一句,我尝试了您的解决方案。 - Johny
@Johny 你可以使用 QGraphicsScene::itemsBoundingRect,它会计算并返回场景上所有项的边界矩形。如果你不想保持纵横比,只需忽略 Qt::KeepAspectRatio 即可。我已经更新了答案。 - Nejat
2
这与我想要的不同 - 这会改变视图。如果我已经放大了视图(以研究某些细节),那么在调整大小时它会再次缩小。 - Johny

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接