I built a simple progress bar (I want to use it in many other programs), but the problem is, if I move the window, or click on anything else the progress window freezes. The script keeps running but the progress window has "Not Responding" and does not update.
from tkinter import *
from tkinter.ttk import *
from datetime import *
import time
def main():
# get start time to calc execution time
start_time = datetime.now().replace(microsecond=0)
print(start_time, "\n")
GB = 100
window = Tk()
percent = StringVar()
text = StringVar()
fleft = StringVar()
download = 0
speed = 5
percentLabel = Label(window, textvariable=percent).pack()
taskLabel = Label(window, textvariable=text).pack()
leftLabel = Label(window, textvariable=fleft).pack()
bar = Progressbar(window,orient=HORIZONTAL,length = 300)
bar.pack(pady=10)
while (download < GB):
download += speed
time.sleep(1)
bar['value']+=(speed/GB)*100
percent.set(str(int((download/GB)*100))+"%")
text.set(str(download)+" files completed!")
fleft.set(str(int(GB - download)) + " left to complete.")
window.update_idletasks()
window.mainloop()
if __name__ == '__main__':
main()
It is not recommended to use loop
and time.sleeep()
in the main thread of tkinter
application as they will block the tkinter
mainloop from updating pending updates and events.
Use .after()
to simulate the loop instead:
from tkinter import *
from tkinter.ttk import *
from datetime import *
import time
def main():
# get start time to calc execution time
start_time = datetime.now().replace(microsecond=0)
print(start_time, "\n")
GB = 100
window = Tk()
percent = StringVar()
text = StringVar()
fleft = StringVar()
download = 0
speed = 5
percentLabel = Label(window, textvariable=percent).pack()
taskLabel = Label(window, textvariable=text).pack()
leftLabel = Label(window, textvariable=fleft).pack()
bar = Progressbar(window,orient=HORIZONTAL,length = 300)
bar.pack(pady=10)
def update_progress(download):
progress = round((download / GB) * 100, 0)
bar['value'] = progress
percent.set(f'{progress:.0f}%')
text.set(f'{download} files completed!')
fleft.set(f'{GB-download} left to complete.')
if download < GB:
window.after(1000, update_progress, download+speed)
update_progress(download) # start the after loop
window.mainloop()
if __name__ == '__main__':
main()