Tkinter 动画越来越快

Tkinter animation goes faster and faster

在我的 tkinter 音乐播放器项目中,我正在使用字幕标签。

为此我使用了一个名为 marquee 的函数。

所以当我运行我的脚本时,跑马灯速度是正常的。 在我前进到下一首歌曲后它会加速等等。

我不知道如何阻止它超速。 我正在以大约 30fps 的速度播放我的动画

有人可以推荐任何方法吗?

def marquee(song_name,fs) :
    global canvas,fps
    fps = fs
    canvas=Canvas(Frame1)
    canvas.grid(row=1)
    text_var= song_name
    text=canvas.create_text(0,-2000,text=text_var,font=('calibri',20,'bold'),fill='black',tags=("marquee",),anchor='w')
    x1,y1,x2,y2 = canvas.bbox("marquee")
    width = x2-x1
    height = y2-y1
    canvas['width']='440'
    canvas['height']=height
    shift()

def shift():
    global canvas,fps

    x1,y1,x2,y2 = canvas.bbox("marquee")
    if(x2<0 or y1<0): 
        x1 = canvas.winfo_width()
        y1 = canvas.winfo_height()//2
        canvas.coords("marquee",x1,y1)
    else:
        canvas.move("marquee", -2, 0)
    canvas.after(1000//fps,shift)

完整代码:https://codeshare.io/zy6vyk

问题是每次调用 marquee 都会开始一个新循环。因此,第一个循环将选取框每帧移动 -2 像素。下次调用 marquee 时,它会启动 another 循环,also 将文本每帧移动 -2 像素。所以现在文本每帧移动 -4 像素。等等。

有几种方法可以解决这个问题。一种是跟踪对 after 的调用的 id,并在开始新循环之前取消它。这将终止旧循环并开始新循环。

第二种解决方案是只调用 marquee 一次以启动一个在程序生命周期内运行的循环。每当歌曲发生变化时,您只需使用新歌曲名称更新现有选取框,而不是创建带有新循环的新选取框。

第二种方案是我推荐的。由于您要将唯一标记添加到选取框文本,因此您可以使用该标记来更改文本。您只需要一个新功能来更改文本。

例如:

def new_song(song_title):
    canvas.itemconfigure("marquee", text=song_title)

有了这个,你只需要在每次歌曲改变时调用 new_song 而不是 marquee

new_song("This is a new song")