+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

2019-07(7)

2019-08(100)

2019-09(109)

2019-10(15)

2019-11(7)

【第四讲】制作动画 -【Python动画设计教程】

发布于2021-01-15 21:11     阅读(969)     评论(0)     点赞(4)     收藏(3)


0

1

2

3

4

5

【Python动画设计教程】系列文章目录
【第一讲】软件准备
【第二讲】搭建界面,Excel读取,图片读取
【第三讲】图像绘制
【第四讲】制作动画




计划2020年1月18日完成
4小时课时,完成动画设计

1 轮换序列的表格

svn地址:svn://gitee.com/bigearrabbit/kevinpython/kevinanimation
检出版本:5

  • 表格设计

按照30度一个图片,360/30 = 12个图片。
每行为一个时间的状态,时间间隔为50毫秒
每列为一个位置的颜色饱和度
保存为文件 loop.xlsx

msCir 0Cir 1Cir 2Cir 3Cir 4Cir 5Cir 6Cir 7Cir 8Cir 9Cir 10Cir 11
GreenGreenGreenGreenGreenGreenGreenGreenGreenGreenGreenGreen
010000000000000
50901000000000000
1008090100000000000
15070809010000000000
200607080901000000000
2505060708090100000000
30040506070809010000000
350304050607080901000000
4002030405060708090100000
45010203040506070809010000
50001020304050607080901000

  • 创建读取表格函数:
    def readExcelTable(self, iFilePath):
        # 打开文件:
        wb = xlrd.open_workbook(iFilePath)
        sheetCount = len(wb.sheets())  # sheet数量
        if sheetCount < 1:
            return []
        sheet = wb.sheet_by_index(0)  # sheet索引从0开始

        if sheet.nrows < 1 or sheet.ncols < 1:
            return []

        contents = []  # 定义一个行数组

        # 逐行读取
        for i in range(sheet.nrows):  # i从0开始
            tmp = []  # 定义一个空数组变量
            # 逐列读取
            for j in range(sheet.ncols):
                value = sheet.cell_value(i, j)
                tmp.append(value)  # add one value
            contents.append(tmp)  # first row
        return contents
  • 创建输出调试表格的函数

    def printTable(self, table):
        # 逐行输出
        for i in range(len(table)):
            print(table[i])  # 逐个输出最后一列
  • 修改OnOpenExcel函数读取和修改表格
    def OnOpenExcel(self):
        print('I am in OnOpenExcel().')
        self.LoopTable = self.readExcelTable("loop.xlsx")  # 打开文件:
        rows = len(self.LoopTable)
        if rows < 1:
            return 1
        self.printTable(self.LoopTable)
        return 0
  • 运行效果:
['ms', 'Cir 0', 'Cir 1', 'Cir 2', 'Cir 3', 'Cir 4', 'Cir 5', 'Cir 6', 'Cir 7', 'Cir 8', 'Cir 9', 'Cir 10', 'Cir 11']
['', 'Green', 'Green', 'Green', 'Green', 'Green', 'Green', 'Green', 'Green', 'Green', 'Green', 'Green', 'Green']
[0.0, 100.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
[50.0, 90.0, 100.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
[100.0, 80.0, 90.0, 100.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
...

2 根据表格轮换图片

svn地址:svn://gitee.com/bigearrabbit/kevinpython/kevinanimation
检出版本:9
修改部分变量,添加函数:

添加一个Loop按钮来显示图片。

    def OnImageLoop(self):
        print('I am in OnImageLoop().')
        LastIndex = len(self.LoopTable) - 3
        if LastIndex < 0:
            return 1
        if self.LoopIndex >= LastIndex:
            self.LoopIndex = 0

        img = self.imgInput.copy()  # 复制一个拷贝
        self.imgOutput = img  # 记录下来

        row = self.LoopTable[self.LoopIndex + 2]
        cols = len(row)
        for i in range(1, cols):
            self.ImageLoop(self.angle, row[i])
            self.angle += 30
            self.angle = self.angle % 360

        self.LoopIndex += 1

        return 0

通过loop的百分比,来循环绘制图像
效果图:
循环效果图

3 使用QTimer控制动画

参考文章: PyQt5 定时器的使用
添加按钮pushButtonAutoLoop,界面文字:Auto Loop
添加2个QLabel,显示动画的id和时间(毫秒)

定义变量:
self.LoopCounter = 0
self.LoopMax = 0

修改函数OnImageLoopAuto,通过self.startTimer(100)启动计时器,100毫秒触发一次,触发后就会运行timerEvent(self, event)函数。

    def OnImageLoopAuto(self):
        if self.time_id > 0:
            return 0  # 防止重复点击启动计时器
        self.time_id = self.startTimer(100)  # 100ms,0.1s
        self.LoopCounter = 0
        self.LoopMax= len(self.LoopTable) - 2
        return 0

重载函数:timerEvent,在达到一定条件下,停止计时器,
通过语句self.killTimer(self.time_id) 来停止。
所以要提前记录下来计时器的id。
但是这个方法不靠谱。容易出问题。
有可能计时器已经被删除了。


    def timerEvent(self, event):
        # 定时器经过设定的时间会调用这个函数,循环调用,直到被kill
        self.LoopCounter += 1
        if self.LoopCounter < 0:
            self.LoopCounter = 0
        self.OnImageLoop()
        self.labelTimeCounter.setText(str(self.LoopCounter))

        if(self.LoopCounter >= self.LoopMax):
            if self.time_id >0 :
            	self.killTimer(self.time_id)	# 结束定时
            self.time_id = -1
        else:
            text = ''
            id = self.LoopCounter + 2
            if id < len(self.LoopTable):
                row = self.LoopTable[id]
                if len(row) > 0:
                    text = str(row[0])
            if text[-2:] == '.0':
                text = text[0:-2]
            self.labelTime.setText(text)
            self.labelTimeCounter.setText(str(self.LoopCounter))

自动动画的效果

4 保存动画

把一个序列的图片,保存为avi视频
请等待,没有完成

5 问题处理

QT Toolbar简单示例

QT menu简单示例

0

1

2

3

4

5

6



所属网站分类: 技术文章 > 博客

作者:what

链接: https://www.pythonheidong.com/blog/article/771939/eecf2725a535145bd932/

来源: python黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

4 0
收藏该文
已收藏

评论内容:(最多支持255个字符)