计划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 11GreenGreenGreenGreenGreenGreenGreenGreenGreenGreenGreenGreen
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简单示例