python - 使用 QVariantAnimation 显示图像列表
问题描述
我在使用 QVariantAnimation 时遇到了一些麻烦。我一直在寻找如何使用它,但我只是不明白该怎么做。我阅读的文档和示例让我更加困惑。
我有一个 png 图像列表,我希望它们在一定时间内从 A 点移动到 B 点,并根据我定义的步骤更改图像。
例如,A 点为 (0, 0) - B 点为 (6, 0),步长为 (2, 0)。
从 (0, 0) 到 (2, 0) 显示 Image1
从 (2, 0) 到 (4, 0) 显示 Image2
从 (4, 0) 到 (6, 0) 显示 Image3
给出这个例子,因为我不明白 QVariantAnimation 过去给他们的起点和终点。
解决方案
有几种方法可以实现您指出的内容(距离非常小,所以我更改了尺寸)。
- 每个部分的这个方法是一个QVariantAnimation,它建立一个新的QPixmap。
from PyQt5 import QtCore, QtGui, QtWidgets, QtWebEngineWidgets
import random
def create_pixmap():
pixmap = QtGui.QPixmap(QtCore.QSize(20, 20))
pixmap.fill(QtGui.QColor(*random.sample(range(255), 3)))
return pixmap
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.m_scene = QtWidgets.QGraphicsScene(
QtCore.QRectF(-200, -200, 400, 400), self
)
view = QtWidgets.QGraphicsView(self.m_scene)
self.setCentralWidget(view)
self.m_pixmap_item = QtWidgets.QGraphicsPixmapItem()
self.m_scene.addItem(self.m_pixmap_item)
datas = [
(QtCore.QPointF(0, 40), create_pixmap()),
(QtCore.QPointF(0, 80), create_pixmap()),
(QtCore.QPointF(0, 120), create_pixmap()),
]
self.data_iter = iter(datas)
self.move()
def move(self):
try:
end_point, pixmap = next(self.data_iter)
self.m_pixmap_item.setPixmap(pixmap)
animation = QtCore.QVariantAnimation(
duration=500,
valueChanged=self.m_pixmap_item.setPos,
finished=self.move,
startValue=self.m_pixmap_item.pos(),
endValue=end_point,
parent=self,
)
animation.start(QtCore.QAbstractAnimation.DeleteWhenStopped)
except StopIteration:
pass
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.resize(640, 480)
w.show()
sys.exit(app.exec_())
- 在此方法中,itemChange 方法被覆盖,以便它从 QPixmap 更改为每个部分。
from PyQt5 import QtCore, QtGui, QtWidgets, QtWebEngineWidgets
import random
def create_pixmap():
pixmap = QtGui.QPixmap(QtCore.QSize(20, 20))
pixmap.fill(QtGui.QColor(*random.sample(range(255), 3)))
return pixmap
class GraphicsPixmapItem(QtWidgets.QGraphicsPixmapItem):
def __init__(self, parent=None):
super(GraphicsPixmapItem, self).__init__(parent)
self.setFlag(QtWidgets.QGraphicsItem.ItemSendsGeometryChanges, True)
self.m_pixmaps = [create_pixmap() for _ in range(3)]
def itemChange(self, change, value):
if change == QtWidgets.QGraphicsItem.ItemPositionChange:
y = self.pos().y()
if 0 <= y < 40:
self.change_pixmap(self.m_pixmaps[0])
elif 40 <= y < 80:
self.change_pixmap(self.m_pixmaps[1])
elif 80 <= y < 120:
self.change_pixmap(self.m_pixmaps[2])
return super(GraphicsPixmapItem, self).itemChange(change, value)
def change_pixmap(self, pixmap):
if self.pixmap() != pixmap:
self.setPixmap(pixmap)
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.m_scene = QtWidgets.QGraphicsScene(
QtCore.QRectF(-200, -200, 400, 400), self
)
view = QtWidgets.QGraphicsView(self.m_scene)
self.setCentralWidget(view)
self.m_pixmap_item = GraphicsPixmapItem()
self.m_scene.addItem(self.m_pixmap_item)
animation = QtCore.QVariantAnimation(
duration=3000,
valueChanged=self.m_pixmap_item.setPos,
startValue=self.m_pixmap_item.pos(),
endValue=QtCore.QPointF(0, 120),
parent=self,
)
animation.start(QtCore.QAbstractAnimation.DeleteWhenStopped)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.resize(640, 480)
w.show()
sys.exit(app.exec_())
推荐阅读
- c# - 如何在电报API的列中放置一个按钮(内联键盘)?
- autofixture - Autofixture create class from 3rd party library that has an inaccessible internal constructor
- python - 如何加快自定义 QSortFilterProxyModel?
- sql - PL/SQL 过程修正
- python - 如何进一步加快 Numba 中的代码速度?
- java - 测量 Java 线程池的任务队列中任务的最大内存使用量
- python - 根据变量字段分组,然后在python中重置计数器(cumcount)
- mysql - 如何在此查询中求和产品价格
- progressive-web-apps - 渐进式 Web 应用程序是离线混合/原生应用程序的可行替代方案吗?
- kotlin - Kotlin 字符串到 Int 或零(默认值)