gpt4 book ai didi

python - 交换图像时保持 QGraphicsView 中的 View /滚动位置

转载 作者:太空宇宙 更新时间:2023-11-03 19:23:37 25 4
gpt4 key购买 nike

我在缩放加载到 QGraphicsView 的 TIFF 图像时遇到问题与 QGraphicsPixmapItem .

问题更多的是保持图像质量以及不会使应用程序阻塞的缩放速度。首先,我只是用缩放后的 QPixmap 替换图像。 - 我用过Qt.FastTransformation当用户按住水平 slider 时,然后当释放 slider 时,使用 Qt.SmoothTransformation 再次用另一个缩放的像素图替换像素图。 。这提供了质量很好的缩放图像,但在图像尺寸开始增加到大于其原始尺寸后,缩放变得不稳定;缩小图像就可以了。

在 QGraphicsView 上使用 QTransform.fromScale() 可以提供更平滑的缩放,但图像质量较低,即使在应用 .setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform | QPainter.HighQualityAntialiasing) 时也是如此。到 QGraphicsView。

我最新的方法是结合这两种方法并使用 QTransform关于QGraphicsView进行平滑缩放,但当用户释放 slider 时替换 QGraphicsView 中的图像带有缩放的像素图。这很好用,但 View 中的位置会丢失 - 用户放大到一个区域,并且由于缩放后的像素图更大,因此当释放 slider 时 View 会跳转到另一个位置,并且更高质量的缩放后的像素图会替换前一个图像。

我认为,由于两个图像的宽度高度比相同,我可以在图像交换之前获取滚动条的百分比,并在交换之后应用相同的百分比,事情应该会顺利进行。这在大多数情况下效果很好,但有时交换图像后 View 仍然会“跳跃”。

我很确定我在这里做了一些非常错误的事情。有谁知道更好的方法来做到这一点,或者有人可以在下面的代码中发现一些可能导致这种跳跃的内容吗?

这是保存/恢复滚动条位置的代码。它们是子类 QGraphicsView 的方法:

def store_scrollbar_position(self):
x_max = self.horizontalScrollBar().maximum()
if x_max:
x = self.horizontalScrollBar().sliderPosition()
self.scroll_x_percentage = x * (100 / float(x_max))

y_max = self.verticalScrollBar().maximum()
if y_max:
y = self.verticalScrollBar().sliderPosition()
self.scroll_y_percentage = y * (100 / float(y_max))


def restore_scrollbar_position(self):
x_max = self.horizontalScrollBar().maximum()
if self.scroll_x_percentage and x_max:
x = x_max * (float(self.scroll_x_percentage) / 100)
self.horizontalScrollBar().setSliderPosition(x)

y_max = self.verticalScrollBar().maximum()
if self.scroll_y_percentage and y_max:
y = y_max * (float(self.scroll_y_percentage) / 100)
self.verticalScrollBar().setSliderPosition(y)

这就是我进行缩放的方法。 self.imageFileQPixmapself.image是我的QGraphicsPixmapItem 。同样,子类 QGraphicsView 的一部分。该方法附在 slider 运动上 highQuality参数设置为False 。在 slider 释放时再次调用 highQualityTrue交换图像。

def setImageScale(self, scale=None, highQuality=True):
if self.imageFile.isNull():
return
if scale is None:
scale = self.scale
self.scale = scale

self.image.setPixmap(self.imageFile)
self.scene.setSceneRect(self.image.boundingRect())
self.image.setPos(0, 0)
if not highQuality:
self.setTransform(QTransform.fromScale(self.scaleFactor, self.scaleFactor))
self.store_scrollbar_position()
else:
self.image.setPixmap(self.imageFile.scaled(self.scaleFactor * self.imageFile.size(),
Qt.KeepAspectRatio, Qt.SmoothTransformation))
self.setTransform(self.transform)
self.scene.setSceneRect(self.image.boundingRect())
self.image.setPos(0, 0)
self.restore_scrollbar_position()
return

如有任何帮助,我们将不胜感激。我现在开始对此感到非常沮丧。

最佳答案

我找到了一个比我第一次发布的代码更好的解决方案。它仍然不完美,但已经有了很大改进。以防万一其他人试图解决类似的问题......

当设置低质量图像时,我将此方法添加到我的 QGraphicsView 中:

def get_scroll_state(self):
"""
Returns a tuple of scene extents percentages.
"""
centerPoint = self.mapToScene(self.viewport().width()/2,
self.viewport().height()/2)
sceneRect = self.sceneRect()
centerWidth = centerPoint.x() - sceneRect.left()
centerHeight = centerPoint.y() - sceneRect.top()
sceneWidth = sceneRect.width()
sceneHeight = sceneRect.height()

sceneWidthPercent = centerWidth / sceneWidth if sceneWidth != 0 else 0
sceneHeightPercent = centerHeight / sceneHeight if sceneHeight != 0 else 0
return sceneWidthPercent, sceneHeightPercent

这被存储在self.scroll_state中。当设置高质量图像时,我调用另一个函数来恢复前一个函数中使用的百分比。

def set_scroll_state(self, scroll_state):
sceneWidthPercent, sceneHeightPercent = scroll_state
x = (sceneWidthPercent * self.sceneRect().width() +
self.sceneRect().left())
y = (sceneHeightPercent * self.sceneRect().height() +
self.sceneRect().top())
self.centerOn(x, y)

这会将中心位置设置为与交换图像之前相同的位置(百分比)。

关于python - 交换图像时保持 QGraphicsView 中的 View /滚动位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8939315/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com