我们看综艺的时候,经常能看到现场的提词板。今天我们就用tkinter做一个简单的提词板,用到了tkinter的label来动态显示文字。
我们就以最近火爆的《想见你》这首歌为例,按照歌词时间来显示歌词。首先我们要准备好歌词文件,一般是lrc的格式,每句歌词前面都有时间,随便去网上找一个,存成txt即可。
歌词文本是这样的:
我们只要分割每行的时间和歌词,然后根据时间更新下一句歌词就行了。由于格式是固定的,为了简便,按照固定位置截取即可,每一行都是从索引11开始为歌词,索引1-9是时间。
下面是主要的算法函数,用按钮来触发:
def showLrc():start = time.time() #按下按钮开始计时,用于判断时间i=""for j in range(len(f)):lrc = f[j].decode().strip() #lrc为当前这一行的内容 for k in range(11,len(lrc)):i+=lrc[k] #每次刷新增加一个字#一共两行,用两个label来显示歌词if j%2==0:mes0.config(text=str(i),font=('黑体', 25),fg='Goldenrod')else:mes1.config(text=str(i),font=('黑体', 25),fg='Goldenrod') time.sleep(0.1) #每隔0.1秒刷新一次top.update_idletasks() #更新界面 i=""#读取下一行的时间,即下一句歌词开始的时间点tiif j+1 < len(f):lrc = f[j+1].decode().strip()m = 10*int(lrc[1]) + int(lrc[2]) #分钟s = 10*int(lrc[4]) + int(lrc[5]) #秒ms = 100*int(lrc[7]) + 10*int(lrc[8]) + int(lrc[9]) #毫秒ti = m*60 + s + ms/1000second = time.time() - start#如果当前计时未到ti,则休眠两个时间的差值if second<ti:time.sleep(ti-second)#用空白来覆盖之前的文本,否则前后两次的文本会重合;#注意这里的顺序和之前相反,才能实现交替更新if j%2==0:mes1.config(text=" ",font=('黑体', 25),fg='Goldenrod')else:mes0.config(text=" ",font=('黑体', 25),fg='Goldenrod')top.update_idletasks()
下面是完整的代码:
import re
import time
from tkinter import *top = tkinter.Tk()
top.title('提词板')
top.geometry(800x100)
f = open('C:/Users/lin042/Desktop/歌词.txt','rb').readlines()
for i in range(2):exec("mes{} = tkinter.Label(text='')".format(i))exec('mes{}.pack()'.format(i))def showImg():start = time.time()i=""for j in range(len(f)):lrc = f[j].decode().strip() for k in range(11,len(lrc)):i+=lrc[k]if j%2==0:mes0.config(text=str(i),font=('黑体', 25),fg='Goldenrod')else:mes1.config(text=str(i),font=('黑体', 25),fg='Goldenrod') time.sleep(0.1)top.update_idletasks()i=""if j+1 < len(f):lrc = f[j+1].decode().strip()m = 10*int(lrc[1]) + int(lrc[2])s = 10*int(lrc[4]) + int(lrc[5])ms = 100*int(lrc[7]) + 10*int(lrc[8]) + int(lrc[9])ti = m*60 + s + ms/1000second = time.time() - startif second<ti:time.sleep(ti-second)if j%2==0:mes1.config(text=" ",font=('黑体', 25),fg='Goldenrod')else:mes0.config(text=" ",font=('黑体', 25),fg='Goldenrod')top.update_idletasks()submit_button = tkinter.Button(top, text ="想见你", font=('黑体', 10),fg='red',width=10,height=2,command = showImg)
submit_button.place(x=10, y=10)
top.mainloop()
注意这个语句:
for i in range(2):
exec("mes{} = tkinter.Label(text='')".format(i))
exec("mes{}.pack()".format(i))
exec用于创建动态的变量名,这里虽然只有两个label的变量,但如果想多行显示的话,就不能一个一个地声明,用这个方法想创建多少个都可以。
下面是成果:
想见你想见你想见你https://www.zhihu.com/video/1238151480139108352打开手机里的音乐,试试能不能对得上歌词吧。
不过这程序运行起来以后,由于程序一直在循环里面跑,不能再动电脑,也不能同时运行其他软件,否则所有动态效果都会卡住,直到歌词全部更新完。
也许这个提词板挺没用的,但用tkinter动态更新文字的方法,记下来也不亏。比如我们还可以用它来做一个抽奖的滚动画面,或者点名(只能实现动态效果,想要外界终止,需要用到after方法和StringVar,这个我们下次再探讨吧!)