我們看綜藝的時候,經常能看到現場的提詞板。今天我們就用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=""
#讀取下一行的時間,即下一句歌詞開始的時間點ti
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/1000
second = 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/1000
second = time.time() - start
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()
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的變量,但如果想多行顯示的話,就不能一個一個地聲明,用這個方法想創建多少個都可以。
好的,感覺看看成果吧 !!!
打開手機里的音樂,試試能不能對得上歌詞吧。
不過這程序運行起來以后,由于程序一直在循環里面跑,不能再動電腦,也不能同時運行其他軟件,否則所有動態效果都會卡住,直到歌詞全部更新完。
也許這個提詞板挺沒用的,但用tkinter動態更新文字的方法,記下來也不虧。比如我們還可以用它來做一個抽獎的滾動畫面,或者點名(只能實現動態效果,想要外界終止,需要用到after方法和StringVar,這個我們下次再探討吧!)