python - 将动画对象附加到列表时不发生动画
问题描述
我在我的应用程序中创建了两个框架和一个按钮,我想在按下该按钮时动画调整框架的大小。我创建了两个函数*(应该工作相同)* 用于动画帧,*(参见下面的代码)*。
如果您按原样运行代码,它将按照我的意愿为框架设置动画,但如果您使用第二个函数 *(我已将其注释掉)*,它将不起作用。我不知道为什么?有人可以解释一下吗。如果可能的话,一个解决方案。
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
import sys
class Test(QMainWindow):
def __init__(self):
super().__init__()
self.resize(500, 500)
self.frame_to_animate()
# Creating items for the app
def frame_to_animate(self):
self.widget = QWidget()
self.setCentralWidget(self.widget)
# Frame to animate 1
self.frame = QFrame(self.widget)
self.frame.setStyleSheet('QFrame {background: red}')
self.frame.resize(100, 100)
# Frame to animate 2
self.frame2 = QFrame(self.widget)
self.frame2.move(0, 250)
self.frame2.setStyleSheet('QFrame {background: yellow}')
self.frame2.resize(100, 100)
self.thing = False
# Button to animate the frame
self.btn = QPushButton(self.widget)
self.btn.setText('Animate the frame')
self.btn.move(300, 200)
self.btn.clicked.connect(self.animation_fctn)
# self.btn.clicked.connect(self.anim_fctn_i_want) # This animation should be working
# I want this way to work, but it's not working
def anim_fctn_i_want(self):
anim_list = []
for item in [self.frame, self.frame2]:
anim_list.append(QPropertyAnimation(item, b"size"))
for anim in anim_list:
anim.setDuration(1000)
if self.thing is False:
anim.setEndValue(QSize(200, 200))
self.thing = True
else:
anim.setEndValue(QSize(100, 100))
self.thing = False
anim.start()
# Creating Animation one by one
def animation_fctn(self):
self.anim = QPropertyAnimation(self.frame, b"size")
self.anim2 = QPropertyAnimation(self.frame2, b"size")
self.anim.setDuration(1000)
self.anim2.setDuration(1000)
if self.thing is False:
self.anim.setEndValue(QSize(200, 200))
self.anim2.setEndValue(QSize(200, 200))
self.thing = True
else:
self.anim.setEndValue(QSize(100, 100))
self.anim2.setEndValue(QSize(100, 100))
self.thing = False
self.anim.start()
self.anim2.start()
if __name__ == "__main__":
app = QApplication(sys.argv)
window = Test()
window.show()
app.exec()
我目前的方法*(工作正常)*的问题是我必须手动为每个项目执行此操作,并且在我的原始代码中,由于项目很多,它会很麻烦,
第二种方法会使它变得简单,但它不起作用。尝试代码,请指出我做错了什么。
首先尝试一下。然后用# self.btn.clicked.connect(self.anim_fctn_i_want) # This animation should be working
解决方案
问题是在这种情况下,动画的范围仅限于列表的范围,而列表是一个变量,会立即被消除,因此动画也是如此,所以看不到它们的效果。解决方案是延长动画的生命周期,为此有几个选项,例如使列表成为类的属性或将父级传递给动画,因为它们是 QObjects,在这种情况下将使用第二个:
def anim_fctn_i_want(self):
for item in (self.frame, self.frame2):
anim = QPropertyAnimation(item, b"size", parent=item)
anim.setDuration(1000)
anim.setEndValue(QSize(100, 100) if self.thing else QSize(200, 200))
anim.start(QAbstractAnimation.DeleteWhenStopped)
self.thing = not self.thing
另一方面,如果您要并行处理多个动画,那么出于性能原因,最好使用 QParallelAnimationGroup:
def anim_fctn_i_want(self):
group_animation = QParallelAnimationGroup(self)
for item in (self.frame, self.frame2):
anim = QPropertyAnimation(item, b"size")
anim.setDuration(1000)
anim.setEndValue(QSize(100, 100) if self.thing else QSize(200, 200))
group_animation.addAnimation(anim)
group_animation.start(QAbstractAnimation.DeleteWhenStopped)
self.thing = not self.thing
推荐阅读
- python-3.x - 根据python中的列表重新排序字典
- python - 如果键与行字符串匹配,则从由 numpy 数组组成的字典的值中获取 csv 中每个行元素的值
- java - 我正在做一个小项目,我在 GUI JAVA Swing 中遇到了这个问题。我已经分离出主要的错误行以便于访问
- c++ - 为什么当输入两个 char[] 时,第一个会变成最后一个?
- git - 使用 git filter-repo 重写历史时如何保持提交哈希不变
- java - 从 C++ Jni 抽象类的具体实现的 java 对象调用私有方法
- android - 如何将 DialogFragment 放在另一个 DialogFragment 上方/下方?
- javascript - 如何使用 Node JS 执行多个 API 调用
- javascript - 不删除 div 中 contenteditable 设置为 true 的子元素
- r - 有没有办法强制ggplot中的非重叠点?