1、創建一個動畫
#-*- coding: utf-8 -*
__author__ = 'geebos'
from PyQt5.Qt import *
class Example(QWidget):
def __init__(self):
super(Example, self).__init__()
layout = QHBoxLayout()
self.setLayout(layout)
widget = QWidget()
widget.setStyleSheet('QWidget{background-color: red;}')
layout.addWidget(widget)
widget.setGeometry(QRect(0, 0, 100, 100))
# 綁定組件和屬性
self.animation = QPropertyAnimation(widget, b'geometry')
# 設置動畫時間
self.animation.setDuration(1000)
# 設置動畫初始狀態
self.animation.setStartValue(QRect(0, 0, 50, 50))
# 設置動畫結束狀態
self.animation.setEndValue(QRect(0, 0, 150, 150))
# 設置動畫播放次數 -1表示無限
self.animation.setLoopCount(-1)
# 開始動畫
self.animation.start()
self.setGeometry(300, 300, 380, 300)
self.setWindowTitle('Animation')
self.show()
if __name__ == "__main__":
app = QApplication([])
ex = Example()
ex.show()
app.exec_()
特別注意:
self.animation
不能改成 animation
,因爲改成後者之後 animation
在初始化函數執行完後引用計數會變成 0,這時 python解釋器會把 animation回收。最終導致本應該無限循環的動畫在播放一段時間後不再播放,或者根本不播放。
運行效果:
2、動畫序列
上一個例子只有放大部分的動畫,我們還需要添加縮小部分的動畫。這種需求可以通過 QSequentialAnimationGroup
來實現:
#-*- coding: utf-8 -*
__author__ = 'geebos'
from PyQt5.Qt import *
class Example(QWidget):
def __init__(self):
super(Example1, self).__init__()
layout = QHBoxLayout()
self.setLayout(layout)
widget = QWidget()
widget.setStyleSheet('QWidget{background-color: red;}')
layout.addWidget(widget)
widget.setGeometry(QRect(0, 0, 100, 100))
self.animation_group = QSequentialAnimationGroup()
# 綁定組件和屬性
# 正向
animation = QPropertyAnimation(widget, b'geometry')
animation.setDuration(1000)
animation.setStartValue(QRect(0, 0, 50, 50))
animation.setEndValue(QRect(0, 0, 150, 150))
# 要添加到動畫序列中的動畫 不能單獨調用 setLoopCount和 start
# animation.setLoopCount(-1)
# animation.start()
self.animation_group.addAnimation(animation)
# 反向
animation = QPropertyAnimation(widget, b'geometry')
animation.setDuration(1000)
animation.setStartValue(QRect(0, 0, 150, 150))
animation.setEndValue(QRect(0, 0, 50, 50))
self.animation_group.addAnimation(animation)
self.animation_group.setLoopCount(-1)
self.animation_group.start()
self.setGeometry(300, 300, 380, 300)
self.setWindowTitle('Animation')
self.show()
if __name__ == "__main__":
app = QApplication([])
ex = Example()
ex.show()
app.exec_()
運行效果:
3、操作其他屬性
Qt自帶的可操作的屬性有限,只支持有 setter的屬性。但是有時候有些屬性沒有 setter,比如 button的 size就沒有對應的 setter函數,只能通過 setFixedSize函數來設置。這時我們可以重載 QPropertyAnimation
來實現我們的需求。
#-*- coding: utf-8 -*
__author__ = 'geebos'
from PyQt5.Qt import *
class PropertyAnimation(QPropertyAnimation):
def __init__(self, target, property):
super(PropertyAnimation, self).__init__(target, property.encode())
self._func = None
def setUpdateFunc(self, func):
# 設置動畫觸發時要執行的函數
self._func = func
def updateCurrentValue(self, value):
if self._func is None:
super(PropertyAnimation, self).updateCurrentValue(value)
else:
self._func(self.targetObject(), value)
class Example(QWidget):
def __init__(self):
super(Example2, self).__init__()
layout = QHBoxLayout()
self.setLayout(layout)
button = QPushButton('點我點我')
button.setFixedSize(QSize(100, 100))
button.setStyleSheet('QWidget{background-color: red;}')
layout.addWidget(button)
self.animation_group = QSequentialAnimationGroup()
def update(target, value):
# 更新函數,在這個函數裏設置 button的大小
target.setFixedSize(value)
# 綁定組件和屬性
# 正向
animation = PropertyAnimation(button, 'size')
animation.setUpdateFunc(update)
animation.setDuration(1000)
animation.setStartValue(QSize(50, 50))
animation.setEndValue(QSize(150, 150))
# 要添加到動畫序列中的動畫 不能單獨調用 setLoopCount和 start
# animation.setLoopCount(-1)
# animation.start()
self.animation_group.addAnimation(animation)
# 反向
animation = PropertyAnimation(button, 'size')
animation.setUpdateFunc(update)
animation.setDuration(1000)
animation.setStartValue(QSize(150, 150))
animation.setEndValue(QSize(50, 50))
self.animation_group.addAnimation(animation)
self.animation_group.setLoopCount(-1)
self.animation_group.start()
self.setGeometry(300, 300, 380, 300)
self.setWindowTitle('Animation')
self.show()
if __name__ == "__main__":
app = QApplication([])
ex = Example()
ex.show()
app.exec_()
運行效果:
如果你不是在簡書看到這篇文章,請移步簡書支持原作者