0

I have this simple program just for my understanding, and when I press "0" I enter into the "def func", it should change the background of the button to red, then wait 3 seconds and print "hello", but when I run it and I press "0", the program first sleeps 3 seconds, and then changes the background and then prints "hello", why?? It should first change the background and then execute the other lines. You can try copying my code:

import time
from tkinter import *
window = Tk()
window.geometry("500x300")
def func(event):
    button.configure(bg="Red")
    time.sleep(3)
    print("hello")
button= Button(window,text= "Hello", font= ('Helvetica 20 '),width=5,height=1,bg="#008BC7")
window.bind("0", func)
button.pack()
constantstranger
  • 9,176
  • 2
  • 5
  • 19
  • 2
    I'm not very familiar with Tk, but I'd bet the issue is that your function blocks the event loop and so the window doesn't redraw until it's done. If you want to do a background task in a GUI app you generally need to do it on another thread to keep the GUI from hanging while the background task finishes. (FWIW if you're just starting off on learning programming, I would recommend sticking to console I/O, which has way fewer of these gotchas.) – Samwise Apr 16 '22 at 16:25
  • Mh but it’s strange because if i write inside the function. print(“hello”) time.sleep(3) print(“how are you”) It works executing first the “print hello” line – Stefano9669 Apr 16 '22 at 16:27
  • @Samwise is on the right track, you can read about the issue [here](https://stackoverflow.com/questions/67618510/how-to-be-sure-that-time-sleep-is-called-only-after-the-previous-command-is-fu) – dylanface Apr 16 '22 at 16:29
  • @Stefano9669 `print` wouldn't need a UI update, it's written into the console... – CherryDT Apr 16 '22 at 16:33
  • 1
    There must be hundreds of similar questions on this site. Have you done any research? `time.sleep` does exactly that, it puts the app to sleep. While it's sleeping it can't refresh the window. – Bryan Oakley Apr 16 '22 at 17:00
  • Sorry Bryan i haven't done any research of similar arguments, if this question is a problem i can delete it, now i found my solution – Stefano9669 Apr 16 '22 at 17:08

1 Answers1

0

Q. Why did all of this happen?
A. Because all changes happen after the function exit.
Try This: Instead of time.sleep(3) write for a in range(10000): print(a) here you can check the background of button change after the loop and the last line which is print('hello') execute.

Don't use time.sleep() when using tkinter library because there is a method in here call Tk().after(timeInMillisecond,function).

Tk().after() method does not stop the program from running it executes the function after the given time below I use the lambda function instead of the normal function.

import time
from tkinter import *
window = Tk()
window.geometry("500x300")
def func(event):
    button.configure(bg="Red")
    window.after(3000,lambda:print('hello'))# edited
button= Button(window,text= "Hello", font= ('Helvetica 20 '),width=5,height=1,bg="#008BC7")
window.bind("0", func)
button.pack()
window.mainloop()

Instead of lambda function, You can also use the normal function here.

import time
from tkinter import *
window = Tk()
window.geometry("500x300")
def print_hello():
    print('hello')
def func(event):
    button.configure(bg="Red")
    window.after(3000,print_hello) # edited
button= Button(window,text= "Hello", font= ('Helvetica 20 '),width=5,height=1,bg="#008BC7")
window.bind("0", func)
button.pack()
window.mainloop()
codester_09
  • 5,622
  • 2
  • 5
  • 27
  • One last question, why if i write: window.after(3000,button.configure(bg="black") doesn'work but with lambda works? Why i have to put lambda? window.after(3000,lambda: button.configure(bg="black") – Stefano9669 Apr 16 '22 at 17:14