如何为场景 Rectangle 设置动画?
How do I animate the scene Rectangle?
我正在尝试使用动画移动我的 QGraphicsScene 矩形,以获得它平滑移动的印象。但我不知道该怎么做。有人可以帮助我吗?我想知道是否可以为 Qtransform 实例设置动画。如果是,我该怎么做?
问题:
1 - 如何为移动场景矩形的平移函数设置动画。我想为它制作动画,因为我希望它看起来很流畅。
2 - 可以为 Qtransform 实例设置动画吗?
这是我的代码:
from PyQt5.QtWidgets import QWidget, QApplication, QHBoxLayout
from PyQt5 import QtGui
from PyQt5 import QtWidgets
from PyQt5 import QtCore
class Example(QWidget):
def __init__(self, parent=None):
super(Example, self).__init__(parent) # this widget has no parent
hbox = QHBoxLayout(self)
self.setMinimumHeight(500)
self.setMinimumWidth(500)
self.button = QtWidgets.QPushButton("move scene", self) # this button is responsible to emit a signal to animate the
# scene translation
self.button.clicked.connect(self.do) # connect to the animation
self.scene = QtWidgets.QGraphicsScene() # instantiate the scene
self.view = QtWidgets.QGraphicsView(self) # instantiate the view
self.view.setScene(self.scene)
hbox.addWidget(self.view) # insert into the layout
hbox.addWidget(self.button) # insert into the layout
self.r = self.view.mapToScene(self.view.viewport().rect()).boundingRect()# take the viewport bounding rectangle
self.view.setSceneRect(self.r) # define the viewport bounding rectangle as the initial scene rectangle
self.scene.addEllipse(self.r, QtGui.QPen(QtGui.QBrush(QtCore.Qt.darkRed), 10, join=QtCore.Qt.RoundJoin))
# draw an ellipse in our scene
self.scene.setBackgroundBrush(QtGui.QBrush(QtCore.Qt.CrossPattern)) # set a grid patter to turn easier to
# see the displacements of objects
def translateSceneSmooth(self, ds: tuple) -> None:
"""
ds = (dx, dy)
:param ds: is the differential in x and y.
:return: None
"""
self.view.setSceneRect(self.view.sceneRect().translated(*ds)) # I want that the animation pass a interpolation
# of a tuple here: starting at (0, 0) and ending at (100, 100)
# I don't know if this approach is correct.
# Because maybe it will not move 100 px.if I have a list of numbers in the form passing through the function:
# [0, 10, 20, 50, 70, 100] maybe it'll move 0+10+20+50+70+100 = 250 px
def do(self, duration=100):
"""
I want the scene rectangle to move smoothly
"""
print('Starting animation')
self._animation = QtCore.QVariantAnimation()
self._animation.setStartValue(0)
self._animation.setEndValue(1000)
self._animation.setDuration(duration)
self._animation.start(QtCore.QAbstractAnimation.DeleteWhenStopped)
self._animation.valueChanged.connect(self.translateSceneSmooth)
print('Ending animation')
if __name__ == "__main__":
app = QApplication([])
ex = Example()
ex.show()
app.exec_()
如果要移动sceneRect,通过计算开始和结束矩形来生成矩形的动画。另一方面,默认情况下,按下的信号传递一个布尔值来覆盖默认值“持续时间”,一个可能的解决方案是使用 pyqtSlot 装饰器使连接签名显式:
from PyQt5 import QtCore, QtGui, QtWidgets
class Example(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Example, self).__init__(parent)
self.setMinimumSize(500, 500)
self.button = QtWidgets.QPushButton("move scene")
# scene translation
self.button.clicked.connect(self.do)
self.scene = QtWidgets.QGraphicsScene()
self.view = QtWidgets.QGraphicsView()
self.view.setScene(self.scene)
hbox = QtWidgets.QHBoxLayout(self)
hbox.addWidget(self.view)
hbox.addWidget(self.button)
self.r = self.view.mapToScene(self.view.viewport().rect()).boundingRect()
self.view.setSceneRect(self.r)
self.scene.addEllipse(
self.r,
QtGui.QPen(QtGui.QBrush(QtCore.Qt.darkRed), 10, join=QtCore.Qt.RoundJoin),
)
self.scene.setBackgroundBrush(QtGui.QBrush(QtCore.Qt.CrossPattern))
@QtCore.pyqtSlot()
def do(self, duration=100):
"""
I want the scene rectangle to move smoothly
"""
ds = QtCore.QPointF(100, 100)
current_rect = self.view.sceneRect()
next_rect = current_rect.translated(ds)
self._animation = QtCore.QVariantAnimation()
self._animation.setStartValue(current_rect)
self._animation.setEndValue(next_rect)
self._animation.setDuration(duration)
self._animation.valueChanged.connect(self.view.setSceneRect)
self._animation.finished.connect(lambda: print("Ending animation"))
self._animation.start(QtCore.QAbstractAnimation.DeleteWhenStopped)
print("Starting animation")
if __name__ == "__main__":
app = QtWidgets.QApplication([])
ex = Example()
ex.show()
app.exec_()
我正在尝试使用动画移动我的 QGraphicsScene 矩形,以获得它平滑移动的印象。但我不知道该怎么做。有人可以帮助我吗?我想知道是否可以为 Qtransform 实例设置动画。如果是,我该怎么做?
问题:
1 - 如何为移动场景矩形的平移函数设置动画。我想为它制作动画,因为我希望它看起来很流畅。
2 - 可以为 Qtransform 实例设置动画吗?
这是我的代码:
from PyQt5.QtWidgets import QWidget, QApplication, QHBoxLayout
from PyQt5 import QtGui
from PyQt5 import QtWidgets
from PyQt5 import QtCore
class Example(QWidget):
def __init__(self, parent=None):
super(Example, self).__init__(parent) # this widget has no parent
hbox = QHBoxLayout(self)
self.setMinimumHeight(500)
self.setMinimumWidth(500)
self.button = QtWidgets.QPushButton("move scene", self) # this button is responsible to emit a signal to animate the
# scene translation
self.button.clicked.connect(self.do) # connect to the animation
self.scene = QtWidgets.QGraphicsScene() # instantiate the scene
self.view = QtWidgets.QGraphicsView(self) # instantiate the view
self.view.setScene(self.scene)
hbox.addWidget(self.view) # insert into the layout
hbox.addWidget(self.button) # insert into the layout
self.r = self.view.mapToScene(self.view.viewport().rect()).boundingRect()# take the viewport bounding rectangle
self.view.setSceneRect(self.r) # define the viewport bounding rectangle as the initial scene rectangle
self.scene.addEllipse(self.r, QtGui.QPen(QtGui.QBrush(QtCore.Qt.darkRed), 10, join=QtCore.Qt.RoundJoin))
# draw an ellipse in our scene
self.scene.setBackgroundBrush(QtGui.QBrush(QtCore.Qt.CrossPattern)) # set a grid patter to turn easier to
# see the displacements of objects
def translateSceneSmooth(self, ds: tuple) -> None:
"""
ds = (dx, dy)
:param ds: is the differential in x and y.
:return: None
"""
self.view.setSceneRect(self.view.sceneRect().translated(*ds)) # I want that the animation pass a interpolation
# of a tuple here: starting at (0, 0) and ending at (100, 100)
# I don't know if this approach is correct.
# Because maybe it will not move 100 px.if I have a list of numbers in the form passing through the function:
# [0, 10, 20, 50, 70, 100] maybe it'll move 0+10+20+50+70+100 = 250 px
def do(self, duration=100):
"""
I want the scene rectangle to move smoothly
"""
print('Starting animation')
self._animation = QtCore.QVariantAnimation()
self._animation.setStartValue(0)
self._animation.setEndValue(1000)
self._animation.setDuration(duration)
self._animation.start(QtCore.QAbstractAnimation.DeleteWhenStopped)
self._animation.valueChanged.connect(self.translateSceneSmooth)
print('Ending animation')
if __name__ == "__main__":
app = QApplication([])
ex = Example()
ex.show()
app.exec_()
如果要移动sceneRect,通过计算开始和结束矩形来生成矩形的动画。另一方面,默认情况下,按下的信号传递一个布尔值来覆盖默认值“持续时间”,一个可能的解决方案是使用 pyqtSlot 装饰器使连接签名显式:
from PyQt5 import QtCore, QtGui, QtWidgets
class Example(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Example, self).__init__(parent)
self.setMinimumSize(500, 500)
self.button = QtWidgets.QPushButton("move scene")
# scene translation
self.button.clicked.connect(self.do)
self.scene = QtWidgets.QGraphicsScene()
self.view = QtWidgets.QGraphicsView()
self.view.setScene(self.scene)
hbox = QtWidgets.QHBoxLayout(self)
hbox.addWidget(self.view)
hbox.addWidget(self.button)
self.r = self.view.mapToScene(self.view.viewport().rect()).boundingRect()
self.view.setSceneRect(self.r)
self.scene.addEllipse(
self.r,
QtGui.QPen(QtGui.QBrush(QtCore.Qt.darkRed), 10, join=QtCore.Qt.RoundJoin),
)
self.scene.setBackgroundBrush(QtGui.QBrush(QtCore.Qt.CrossPattern))
@QtCore.pyqtSlot()
def do(self, duration=100):
"""
I want the scene rectangle to move smoothly
"""
ds = QtCore.QPointF(100, 100)
current_rect = self.view.sceneRect()
next_rect = current_rect.translated(ds)
self._animation = QtCore.QVariantAnimation()
self._animation.setStartValue(current_rect)
self._animation.setEndValue(next_rect)
self._animation.setDuration(duration)
self._animation.valueChanged.connect(self.view.setSceneRect)
self._animation.finished.connect(lambda: print("Ending animation"))
self._animation.start(QtCore.QAbstractAnimation.DeleteWhenStopped)
print("Starting animation")
if __name__ == "__main__":
app = QtWidgets.QApplication([])
ex = Example()
ex.show()
app.exec_()