pyqt5 動畫學習(四) 旋轉動畫,使用QGraphicsView讓自己的控件旋轉起來


今天學有所成,趕緊記下今天的成果

之前三篇文章分別演示了空間的大小改變,移動,及顏色變化。在后續研究旋轉的過程中即為艱難

如果你是使用pyqt4,那么使用QGraphicsItemAnimation便可以輕松達到旋轉的效果,這里不再詳述

 

可惜到了pyqt5 

 

於是查閱各種英文資料,我分別嘗試了QGraphicsRotation,QGraphicsTransform,QTransform效果都不太理想,QTransform是可以實現的,但是太復雜

最后我找到了一種極為簡單的方法就是在使用QGraphicsView的各種item時,可以直接setRotation讓對象旋轉起來,下面來看看代碼,這里直接在對象上寫一個動畫:

class Ball(QObject):
    def __init__(self):
        super().__init__()
        pixmap = QPixmap("../star.png")
        scaledPixmap = pixmap.scaled(50, 55)
        self.animation()

        self.pixmap_item = QGraphicsPixmapItem(scaledPixmap)
        self.pixmap_item.setTransformOriginPoint(25, 27.5)  # 設置中心為旋轉
        self._set_pos(QPointF(5, 30))  # 設置圖標的初始位置

    def _set_pos(self, pos):
        self.pixmap_item.setPos(pos)

    def _set_rotation(self, angle):
        self.pixmap_item.setRotation(angle.x())  # 旋轉度數

    def animation(self):
        self.anim = QPropertyAnimation(self, b'pos')
        self.anim.setDuration(1000)
        self.anim.setStartValue(QPointF(5, 30))
        self.anim.setKeyValueAt(0.3, QPointF(144, 30))
        self.anim.setKeyValueAt(0.5, QPointF(54, 90))
        self.anim.setKeyValueAt(0.8, QPointF(240, 250))
        self.anim.setEndValue(QPointF(300, 60))

        self.anim2 = QPropertyAnimation(self, b'rotation')
        self.anim2.setDuration(1000)
        self.anim2.setStartValue(QPointF(0, 1))
        self.anim2.setEndValue(QPointF(360, 1))

    pos = pyqtProperty(QPointF, fset=_set_pos)
    rotation = pyqtProperty(QPointF, fset=_set_rotation)

這里可以看到我用QpointF把數字傳進去,然后再取angle.x()作為度數,這樣對象就可以旋轉了

下面我對對象進行了加工,結合前面幾篇動畫文章,我做了一個按一定軌跡自轉的動畫。

這里使用了QGraphicsView界面,我們可以通過QGraphicsView這個界面創建各種QGraphicsScene場景,然后就可以把各種對象弄到這個場景里面去,非常方面

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

"""
Author: semishigure
Website: zetcode.com
Last edited: 2018.03.09
"""

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

import cgitb
import sys

cgitb.enable(format='text')  # 解決pyqt5異常只要進入事件循環,程序就崩潰,而沒有任何提示


class Ball(QObject):
    def __init__(self):
        super().__init__()
        pixmap = QPixmap("../star.png")
        scaledPixmap = pixmap.scaled(50, 55)
        self.animation()

        self.pixmap_item = QGraphicsPixmapItem(scaledPixmap)
        self.pixmap_item.setTransformOriginPoint(25, 27.5)  # 設置中心為旋轉
        self._set_pos(QPointF(5, 30))  # 設置圖標的初始位置

    def _set_pos(self, pos):
        self.pixmap_item.setPos(pos)

    def _set_rotation(self, angle):
        self.pixmap_item.setRotation(angle.x())  # 旋轉度數

    def animation(self):
        self.anim = QPropertyAnimation(self, b'pos')
        self.anim.setDuration(1000)
        self.anim.setStartValue(QPointF(5, 30))
        self.anim.setKeyValueAt(0.3, QPointF(144, 30))
        self.anim.setKeyValueAt(0.5, QPointF(54, 90))
        self.anim.setKeyValueAt(0.8, QPointF(240, 250))
        self.anim.setEndValue(QPointF(300, 60))

        self.anim2 = QPropertyAnimation(self, b'rotation')
        self.anim2.setDuration(1000)
        self.anim2.setStartValue(QPointF(0, 1))
        self.anim2.setEndValue(QPointF(360, 1))

    pos = pyqtProperty(QPointF, fset=_set_pos)
    rotation = pyqtProperty(QPointF, fset=_set_rotation)


class Myview(QGraphicsView):
    def __init__(self):
        super().__init__()
        self._set_color(QColor(105, 105, 105))
        self.iniAnimation()

    def _set_color(self, col):
        self.palette = QPalette()
        # self.palette.setColor(self.backgroundRole(), col)
        self.palette.setBrush(self.backgroundRole(), col)
        self.setPalette(self.palette)

    def iniAnimation(self):
        self.anim3 = QPropertyAnimation(self, b'color')
        self.anim3.setDuration(1000)
        self.anim3.setStartValue(QColor(105, 105, 105))
        self.anim3.setKeyValueAt(0.1, QColor(255, 255, 240))
        self.anim3.setKeyValueAt(0.3, QColor(219, 225, 171))
        self.anim3.setKeyValueAt(0.7, QColor(148, 214, 184))
        self.anim3.setEndValue(QColor(86, 199, 170))

    color = pyqtProperty(QColor, fset=_set_color)


class MainWindow(Myview):

    def __init__(self):
        super().__init__()

        self.initView()
        self.iniui()

    def initView(self):
        self.ball = Ball()
        self.scene = QGraphicsScene(self)
        self.scene.setSceneRect(0, 0, 300, 300)
        self.scene.addItem(self.ball.pixmap_item)
        self.setScene(self.scene)

        self.setWindowTitle("Ball animation")
        self.setRenderHint(QPainter.Antialiasing)
        self.setGeometry(300, 300, 500, 350)
        self.show()

    def iniui(self):
        self.btn = QPushButton("開始")
        self.maingrid = QHBoxLayout()
        self.maingrid.addStretch(1)
        self.maingrid.addWidget(self.btn)
        self.btn.clicked.connect(self.runAnim)

        self.maingrid2 = QVBoxLayout()
        self.maingrid2.addStretch(1)
        self.maingrid2.addLayout(self.maingrid)

        self.setLayout(self.maingrid2)

    def runAnim(self):
        self.ball.anim.start()
        self.ball.anim2.start()
        self.anim3.start()


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

界面效果:

 

備注:

讓我們創建好QGraphicsView后,需要再創建一個QGraphicsScene場景,然后通過self.scene.addItem(self.ball.pixmap_item)把對象添加到場景里面,最后再通過self.setScene(self.scene)把場景添加進界面即可

 


免責聲明!

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



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