• 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))

  • 相关阅读:
    MyEclipse中的几种查找方法
    WebLogic初学笔记
    CountDownLatch源码分析
    linux--句柄相关
    linux命令--wc
    Spring源码解析(九)--再来说说三级缓存
    定位JVM内存泄漏常用命令和方法
    Mybatis整合Spring之MapperFactoryBean怎么拿到的SqlSessionFactory
    Mybatis3.3.0 Po类有LocalDateTime字段报错
    时间范围查询优化技巧
  • 原文地址:https://www.cnblogs.com/semishigure/p/8492983.html
Copyright © 2020-2023  润新知