Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
538 views
in Technique[技术] by (71.8m points)

python - Tkinter: Updating progressbar when a function is called

Imagine the following simple example:

def doNothing():
  sleep(0.5)
  barVar.set(10)
  sleep(0.5)
  barVar.set(20)
  sleep(0.5)
  barVar.set(30)

mainWindow = Tk()
barVar = DoubleVar()
barVar.set(0)
bar = Progressbar(mainWindow, length=200, style='black.Horizontal.TProgressbar', variable=barVar, mode='determinate')
bar.grid(row=1, column=0)
button= Button(mainWindow, text='Click', command=doNothing)
button.grid(row=0, column=0)
mainWindow.mainloop()

What I get when I run this, the progressbar is already at 30% when clicking the button, no progress in front of me. Like attached:

enter image description here

What I need: I can see the progress in front of me (not hanging then suddenly 30%)

Update: I upadted the code according to @Bernhard answer, but still I can not see the progress in front of me. Just a sudden jump of 30% after waiting 1.5 sec

Seocnd Update: I'm only using sleep here as a simulation for a process that takes time, like connecting over ssh and grabing some info.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Do not use sleep() in tkinter. The entire reason for you problem is sleep() will freeze tkinter until it is done with its count so what you are seeing is a frozen program and when the program is finally released its already set to 30 percent on the next mainloop update.

Instead we need to use Tkinter's built in method called after() as after is specifically for this purpose.

import tkinter as tk import tkinter.ttk as ttk

mainWindow = tk.Tk()

def update_progress_bar():
    x = barVar.get()
    if x < 100:
        barVar.set(x+10)
        mainWindow.after(500, update_progress_bar)
    else:
        print("Complete")


barVar = tk.DoubleVar()
barVar.set(0)
bar = ttk.Progressbar(mainWindow, length=200, style='black.Horizontal.TProgressbar', variable=barVar, mode='determinate')
bar.grid(row=1, column=0)
button= tk.Button(mainWindow, text='Click', command=update_progress_bar)
button.grid(row=0, column=0)

mainWindow.mainloop()

If you want the bar to appear to move smoothly you will need to speed up the function call and reduce the addition to the DoubbleVar.

import tkinter as tk
import tkinter.ttk as ttk


mainWindow = tk.Tk()

def update_progress_bar():
    x = barVar.get()
    if x < 100:
        barVar.set(x+0.5)
        mainWindow.after(50, update_progress_bar)
    else:
        print("Complete")


barVar = tk.DoubleVar()
barVar.set(0)
bar = ttk.Progressbar(mainWindow, length=200, style='black.Horizontal.TProgressbar', variable=barVar, mode='determinate')
bar.grid(row=1, column=0)
button= tk.Button(mainWindow, text='Click', command=update_progress_bar)
button.grid(row=0, column=0)

mainWindow.mainloop()

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...