Home > Enterprise >  Tkinter animation goes faster and faster
Tkinter animation goes faster and faster

Time:12-02

On my tkinter music player project , where I am working with a marquee label.

To that i use a function named marquee.

So when i run my script, marquee speed is normal. After i advance to next song it speeds up and so on.

I cannot figure how to stop it from speeding. Iam playing my animation about 30fps

Can anybody suggest any method ?

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)

Full code : https://codeshare.io/zy6vyk

CodePudding user response:

The problem is that each time you call marquee you are starting a new loop. So, the first loop moves the marquee by -2 pixels each frame. The next time you call marquee it starts another loop, also moving the text by -2 pixels each frame. So now the text moves -4 pixels each frame. And so on.

There are a couple of ways to solve this. One is to keep track of the id of the call to after, and cancel it before starting a new loop. That will terminate the old loop and start a new loop.

The second solution is to only call marquee a single time to start a single loop that runs for the life of the program. Whenever a song changes, instead of creating a new marquee with a new loop you just update the existing marquee with the new song title.

The second solution is what I recommend. Since you're adding a unique tag to the marquee text, you can use that tag to change the text. You just need a new function for changing the text.

For example:

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

With that, you just need to call new_song instead of marquee each time the song changes.

new_song("This is a new song")
  • Related