首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >动画QGraphicsView fitInView方法

动画QGraphicsView fitInView方法
EN

Stack Overflow用户
提问于 2021-12-14 21:24:32
回答 2查看 113关注 0票数 0

因此,让我说我有一个简单的QGraphicsView和QGraphicsScene,我想动画的视图顺利滚动/缩放到场景中的任意QRecF。我知道您可以调用view.fitInView()view.centerOn()在rect上“帧”,但是这些都不能提供太多的动画。我可以反复调用view.centerOn()来很好地动画滚动,但这不能处理缩放。我认为我需要修改视图的视图,但我不太确定如何做到这一点(调用view.setSceneRect()似乎很有希望,但这只是设置视图可以管理的区域,而不是它目前正在“查看”的区域)。

基于一些C++的答案,我想出了如何重写fitInView方法,但是我仍然停留在不调用centerOn的情况下将视图转换为look at的部分。到目前为止,我的情况如下:

代码语言:javascript
复制
view = QtWidgets.QGraphicsView()
scene = QtWidgets.QGraphicsScene()
targetRect = QtCore.QRectF(500, 500, 500, 500)

viewRect = view.viewport().rect()
sceneRect = view.transform().mapRect(targetRect)

xratio = viewRect.width() / sceneRect.width()
yratio = viewRect.height() / sceneRect.height()

# keep aspect
xratio = yratio = min(xratio, yratio)

# so... now what to do with the ratio? I need to scale the view rect somehow.

# animation
start = view.mapToScene(viewRect).boundingRect()
end = sceneRect # I guess?

animator = QtCore.QVariantAnimation()
animator.setStartValue(start)
animator.setEndValue(end)
animator.valueChanged.connect(view.????) # what am I setting here?
animator.start()
EN

回答 2

Stack Overflow用户

发布于 2021-12-14 22:30:13

我走了很多弯弯曲曲的路,结果得到了一个非常简单的答案,我想我会把它发出去,以防有人发现它同时对滚动和缩放都有帮助:

代码语言:javascript
复制
view = QtWidgets.QGraphicsView()
scene = QtWidgets.QGraphicsScene()
targetRect = QtCore.QRectF(500, 500, 500, 500)


animator = QtCore.QVariantAnimation()
animator.setStartValue(view.mapToScene(view.viewport().rect()).boundingRect())
animator.setEndValue(targetRect)
animator.valueChanged.connect(lambda x: view.fitInView(x, QtCore.Qt.KeepAspectRatio))
animator.start()
票数 0
EN

Stack Overflow用户

发布于 2021-12-14 23:43:09

一个简单的基本解决方案是映射目标矩形并使用该值作为动画的结束值。

请注意,这个解决方案实际上并不是最优的,原因有两个:

它完全依赖于transformation;

  • since,它必须通过检查当前的视口大小来计算动画的每一次迭代中整个场景的转换;一个更好(但更复杂)的实现是使用scale()setTransform(),并在当前映射的setTransform()矩形上调用centerOn() --场景重排可能比视图显示的要小,放大可能会有点尴尬;

代码语言:javascript
复制
class SmoothZoomGraphicsView(QtWidgets.QGraphicsView):
    def __init__(self):
        super().__init__()
        scene = QtWidgets.QGraphicsScene()
        self.setScene(scene)
        self.pixmap = scene.addPixmap(QtGui.QPixmap('image.png'))
        self.animation = QtCore.QVariantAnimation()
        self.animation.valueChanged.connect(self.smoothScale)
        self.setTransformationAnchor(self.AnchorUnderMouse)

    def wheelEvent(self, event):
        viewRect = self.mapToScene(self.viewport().rect()).boundingRect()
        # assuming we are using a basic x2 or /2 ratio, we need to remove
        # a quarter of the width/height and translate to half the position
        # betweeen the current rectangle and cursor position, or add half
        # the size and translate to a negative relative position
        if event.angleDelta().y() > 0:
            xRatio = viewRect.width() / 4
            yRatio = viewRect.height() / 4
            translate = .5
        else:
            xRatio = -viewRect.width() / 2
            yRatio = -viewRect.height() / 2
            translate = -1
        finalRect = viewRect.adjusted(xRatio, yRatio, -xRatio, -yRatio)
        cursor = self.viewport().mapFromGlobal(QtGui.QCursor.pos())
        if cursor in self.viewport().rect():
            line = QtCore.QLineF(viewRect.center(), self.mapToScene(cursor))
            finalRect.moveCenter(line.pointAt(translate))
        self.animation.setStartValue(viewRect)
        self.animation.setEndValue(finalRect)
        self.animation.start()

    def smoothScale(self, rect):
        self.fitInView(rect, QtCore.Qt.KeepAspectRatio)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70355703

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档