python - 在 PyQt5 Python 中使用 QPropertyAnimation 处理二维数组
问题描述
当我使用带有一维数组的 QPropertyAnimation 时,没有问题。它接受所有的动画命令。但是,我想清除我的代码,因为我会处理很多图像。所以我尝试将二维数组用于图像及其动画。
与一维数组相同的逻辑(不在代码中):
self.animG = []
for i in range(3):
self.animG.append(QPropertyAnimation(self.welcome, b"geometry"))
...
...
...
for i in range(len(self.animG)):
if i == 0:
self.animG[i].setDuration(1000)
self.animG[i].setStartValue(QRect(-1920, 0, 1920, 1080))
self.animG[i].setEndValue(QRect(0, 0, 1920, 1080))
elif i == 1:
self.animG[i].setDuration(2000)
self.animG[i].setStartValue(QRect(0, 0, 1920, 1080))
self.animG[i].setEndValue(QRect(0, 0, 1920, 1080))
else:
self.animG[i].setDuration(1000)
self.animG[i].setStartValue(QRect(0, 0, 1920, 1080))
self.animG[i].setEndValue(QRect(1920, 0, 1920, 1080))
...
...
for i in range(3):
self.anim_group.addAnimation(self.animG[i])
上面的代码完美运行,但我不想为每张图片创建这些主题。所以我认为类似下面的内容(所有代码,但需要部分指出):
from PyQt5 import QtGui, QtWidgets, QtCore
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QFrame
from PyQt5.QtCore import QPropertyAnimation, QRect, QPoint
import sys, time
class Window(QMainWindow):
def __init__(self):
super().__init__()
self.title = "Image Slider with PyQt5"
self.InitWindow()
def InitWindow(self):
self.setWindowTitle(self.title)
screenx = QtWidgets.QDesktopWidget().screenGeometry()
print(screenx.width(), screenx.height())
self.welcome = QtWidgets.QLabel(self)
self.pixmapW = QtGui.QPixmap('Raspberry/WELCOME.jpg')
self.welcome.setPixmap(self.pixmapW)
self.label = QtWidgets.QLabel(self)
self.pixmap = QtGui.QPixmap('Raspberry/image.jpg')
self.label.setPixmap(self.pixmap)
self.label2 = QtWidgets.QLabel(self)
self.pixmap2 = QtGui.QPixmap('Raspberry/image2.jpg')
self.label2.setPixmap(self.pixmap2)
self.label.setGeometry(0, -1080, self.pixmap.width(), self.pixmap.height())
self.label2.setGeometry(0, -1080, self.pixmap2.width(), self.pixmap2.height())
self.welcome.setGeometry(0, 0, self.pixmapW.width(), self.pixmapW.height())
self.button = QPushButton("Start", self)
self.button.setGeometry(((screenx.width() - 120)//2), ((screenx.height() - 80)//2), 120, 80)
# QPropertyAnimation decleration
self.propAnim = []
self.propAnim.append(QPropertyAnimation(self.welcome, b"geometry"))
self.propAnim.append(QPropertyAnimation(self.label, b"geometry"))
self.propAnim.append(QPropertyAnimation(self.label2, b"geometry"))
# Defining 2D array for images, and to embed QPropertAnimations
self.imageCount, self.animCount = 3, 3
self.animations = [[0 for x in range(self.imageCount)] for y in range(self.animCount)]
# Embed 3 same animations scene to all images
for i in range(self.imageCount):
for j in range(self.animCount):
self.animations[i][j] = (self.propAnim[i])
self.anim_group = QtCore.QSequentialAnimationGroup()
self.button.clicked.connect(self.doAni)
self.anim_group.finished.connect(self.doAni)
self.showMaximized()
def doAni(self):
self.label.setGeometry(0, -1080, self.pixmap.width(), self.pixmap.height())
self.label2.setGeometry(0, -1080, self.pixmap2.width(), self.pixmap2.height())
self.welcome.setGeometry(0, -1080, self.pixmapW.width(), self.pixmapW.height())
for i in range(self.imageCount):
for j in range(self.animCount):
if j == 0:
self.animations[i][j].setDuration(2000)
self.animations[i][j].setStartValue(QRect(-1920, 0, 1920, 1080))
self.animations[i][j].setEndValue(QRect(0, 0, 1920, 1080))
elif j == 1:
self.animations[i][j].setDuration(2000)
self.animations[i][j].setStartValue(QRect(0, 0, 1920, 1080))
self.animations[i][j].setEndValue(QRect(0, 0, 1920, 1080))
elif j == 2:
self.animations[i][j].setDuration(2000)
self.animations[i][j].setStartValue(QRect(0, 0, 1920, 1080))
self.animations[i][j].setEndValue(QRect(1920, 0, 1920, 1080))
else:
pass
# HERE IS THE PROBLEMATIC PART, IT ONLY AND ONLY ACCEPTS 3rd ANIMATIONS FOR ALL IMAGES
# NORMALLY IT SHOULD MAKE 9 MOVEMENTS TO COMPLETE SCENE
# HOWEVER IT MAKES ONLY 3 MOVEMENTS
for i in range(self.imageCount):
for j in range(self.animCount):
self.anim_group.addAnimation(self.animations[i][j])
self.anim_group.start()
if __name__ == '__main__':
App = QApplication(sys.argv)
window = Window()
sys.exit(App.exec())
正如您在代码的最后注释部分看到的,它必须制作 9 个动画动作,但它只制作了 3 个动画,这是所有图像的最后一个动画!
解决方案
如果你想有 9 个动画,你必须创建 9 个动画。您只是使用 3 并不断更改它们的开始/结束值。
无需创建不必要的列表,只需为动画创建一个列表,并将它们附加到每个项目。您也不需要为列表计数使用实例属性,并且您可以使用预定义的值列表以及在动画和zip()
值之间循环。
self.animations = []
for i, widget in enumerate((self.welcome, self.label, self.label2)):
widgetAnimations = []
for j in range(self.animCount):
widgetAnimations.append(QPropertyAnimation(widget, b"geometry"))
self.animations.append(widgetAnimations)
# ...
def doAni(self):
values = (
(QRect(-1920, 0, 1920, 1080), QRect(0, 0, 1920, 1080)),
(QRect(0, 0, 1920, 1080), QRect(0, 0, 1920, 1080)),
(QRect(0, 0, 1920, 1080), QRect(1920, 0, 1920, 1080)),
)
for widgetAnimations in self.animations:
for animation, (start, end) in zip(widgetAnimations, values):
animation.setStartValue(start)
animation.setEndValue(end)
animation.setDuration(2000)
self.anim_group.addAnimation(animation)
请记住,如果要添加“暂停”动画,则应使用QPauseAnimation。
推荐阅读
- spring - Springboot中如何根据HTTP响应码进行重试
- database-design - 是否允许更新事实表的一行?
- asp.net - 基于 Route 参数的 ASP.NET Core 参数注入
- c# - 果园核心问题以编程方式添加模块
- scala - 输出时间戳列值在 Scala Spark 中的写入操作期间发生变化?
- node.js - 如何跟踪 AWS CloudWatch Log Stream 日志?
- sql - 连接表选择仅存在于一个表中的值
- stored-procedures - 我正在寻找通过 SQL Workbench/J 上的宏运行变量列表
- google-apps-script - 如何检索 Javascript HTML 文件中的变量,然后将其映射到 code.gs 函数
- sql - 在 CASE 语句 TSQL 中赋值会出错