所以假設我有一個簡單的 QGraphicsView 和 QGraphicsScene,我想為視圖設定影片以平滑滾動/縮放到場景中的任意 QRecF。我知道您可以在 rect 上呼叫view.fitInView()或view.centerOn()“構圖”,但是這些都沒有提供太多影片。我可以反復呼叫view.centerOn()以很好地為滾動設定影片,但這不能處理縮放。我相信我需要修改視圖的視口,但我不太確定如何做到這一點(呼叫view.setSceneRect()看起來很有希望,但這只是設定了視圖可以管理的區域,而不是它當前正在“查看”的區域)。
基于一些 C 答案,我想出了如何重新撰寫fitInView大部分方法,但是我被困在我實際將視圖轉換到look at場景的不同部分而不呼叫centerOn. 這是我到目前為止所擁有的:
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()
uj5u.com熱心網友回復:
我走了許多曲折的道路,最終得到了一個非常簡單的答案,我想我會發布它,以防有人發現同時為滾動和縮放設定影片很有用:
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()
uj5u.com熱心網友回復:
一個簡單的基本解決方案是映射目標矩形并將該值用作影片的最終值。
請注意,此解決方案并不是真正的最佳解決方案,原因有兩個:
- 它完全依賴于
fitInView(),它必須通過檢查當前視口大小來計算影片每次迭代時整個場景的變換;更好(但更復雜)的實作是使用scale()orsetTransform()并且還呼叫centerOn()轉換的當前映射矩形; - 由于場景矩形可能比視口顯示的要小,因此縮小可能有點尷尬;
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)
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/383832.html
標籤:Python 动画片 pyqt 图形视图 qgraphicsscene
