pyqt5 動畫學習(三) 指定控件的移動軌跡


這一篇來講解自定義控件的移動軌跡

原理:我們采用QPainterPath先畫一個弧線,然后加載一個物體讓物體移動,設置100個關鍵幀,每個關鍵幀物體的坐標位置就是弧線的坐標位置,這樣就能達到按照指定軌跡移動

 

首先,我們重寫QLabel,加載一個小黑球到QLabel上

class Ball(QLabel):
    def __init__(self, parent):
        super(Ball, self).__init__(parent)

        self.pix = QPixmap("../ball.png")  # 加載一個ball的圖片
        self.h = self.pix.height()  # ball的高度
        self.w = self.pix.width()  # ball的寬度

        self.setPixmap(self.pix)  # 把ball加載到label上

    def _set_pos(self, pos):
        self.move(pos.x() - self.w / 2, pos.y() - self.h / 2)

    pos = pyqtProperty(QPointF, fset=_set_pos)

 

然后我們用QPainterPath來畫弧線,先設置弧線:

    def initView(self):
        self.path = QPainterPath()
        self.path.moveTo(30, 30)
        self.path.cubicTo(30, 30, 200, 350, 350, 30)  # 設置弧線的樣子

再通過paintEvent繪制弧線:

    def paintEvent(self, e):
        qp = QPainter()
        qp.begin(self)
        qp.setRenderHint(QPainter.Antialiasing)
        qp.drawPath(self.path)  # 畫弧線
        qp.end()

 

最后組合起來就行了,剩下的不難,下面是完整代碼:

#!/usr/bin/python3
# -*- coding: utf-8 -*-

"""
PyQt5 Animation tutorial

This program will show along curve with QPropertyAnimation.

Author: Semishigure 401219180@qq.com
Last edited: 2018.03.02
"""

from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
import sys


class Ball(QLabel):
    def __init__(self, parent):
        super(Ball, self).__init__(parent)

        self.pix = QPixmap("../ball.png")  # 加載一個ball的圖片
        self.h = self.pix.height()  # ball的高度
        self.w = self.pix.width()  # ball的寬度

        self.setPixmap(self.pix)  # 把ball加載到label上

    def _set_pos(self, pos):
        self.move(pos.x() - self.w / 2, pos.y() - self.h / 2)

    pos = pyqtProperty(QPointF, fset=_set_pos)


class Example(QWidget):
    def __init__(self):
        super(Example, self).__init__()
        self.initView()
        self.initAnimation()

    def initView(self):
        self.path = QPainterPath()
        self.path.moveTo(30, 30)
        self.path.cubicTo(30, 30, 200, 350, 350, 30)  # 設置弧線的樣子

        self.ball = Ball(self)
        self.ball.pos = QPointF(30, 30)  # 設置ball起點位置,這里就是弧線的起點位置

        self.setWindowTitle("Animation along curve")
        self.setGeometry(300, 300, 400, 300)
        self.show()

    def paintEvent(self, e):
        qp = QPainter()
        qp.begin(self)
        qp.setRenderHint(QPainter.Antialiasing)
        qp.drawPath(self.path)  # 畫弧線
        qp.end()

    def initAnimation(self):
        self.anim = QPropertyAnimation(self.ball, b'pos')
        self.anim.setDuration(3000)
        self.anim.setStartValue(QPointF(30, 30))

        vals = [p / 100 for p in range(0, 101)]

        for i in vals:
            self.anim.setKeyValueAt(i, self.path.pointAtPercent(i))  # 設置100個關鍵幀

        self.anim.setEndValue(QPointF(350, 30))
        self.anim.start()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

界面預覽效果:

 

備注:

1、關鍵幀的范圍值為0-1,我們在其中創建100個點,即[0.01, 0.02, 0.03, 0.04...0.98, 0.99, 1.00],這里直接使用for循環 vals = [p / 100 for p in range(0, 101)]

2、通過i傳遞百分比到self.path.pointAtPercent()就可以拿到弧線的對應坐標QPoinF,所以關鍵幀就可以設置成self.anim.setKeyValueAt(i, self.path.pointAtPercent(i))

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM