Lucas N
Lucas N

Reputation: 69

Python tkinter time.sleep()

How come when I run my code, it will sleep for 3 seconds first, then execute the 'label' .lift() and change the text? This is just one function of many in the program. I want the label to read "Starting in 3...2...1..." and the numbers changing when a second has passed.

def predraw(self):
    self.lost=False
    self.lossmessage.lower()
    self.countdown.lift()
    self.dx=20
    self.dy=0
    self.delay=200
    self.x=300
    self.y=300
    self.foodx=self.list[random.randint(0,29)]
    self.foody=self.list[random.randint(0,29)]
    self.fillcol='blue'
    self.canvas['bg']='white'
    self.lossmessage['text']='You lost! :('
    self.score['text']=0
    self.countdown['text']='Starting in...3'
    time.sleep(1)
    self.countdown['text']='Starting in...2'
    time.sleep(1)
    self.countdown['text']='Starting in...1'
    time.sleep(1)
    self.countdown.lower()
    self.drawsnake()

Upvotes: 1

Views: 1175

Answers (1)

Bryan Oakley
Bryan Oakley

Reputation: 386332

It does this because changes in widgets only become visible when the UI enters the event loop. You aren't allowing the screen to update after calling sleep each time, so it appears that it's sleeping three seconds before changing anything.

A simple fix is to call self.update() immediately before calling time.sleep(1), though the better solution is to not call sleep at all. You could do something like this, for example:

self.after(1000, lambda: self.countdown.configure(text="Starting in...3"))
self.after(2000, lambda: self.countdown.configure(text="Starting in...2"))
self.after(3000, lambda: self.countdown.configure(text="Starting in...1"))
self.after(4000, self.drawsnake)

By using after in this manner, your GUI remains responsive during the wait time and you don't have to sprinkle in calls to update.

Upvotes: 5

Related Questions