问题
The code below createds a Tkinter root window with a button. The button is bound to a simple function which should display a progressbar widget momentarily. Whilst the print statements run as expected, the progress bar is never displayed. Any clues?
from Tkinter import *
import ttk
from time import sleep
root = Tk()
def foo():
print 'starting...'
pb = ttk.Progressbar(root, mode='indeterminate')
pb.pack()
sleep(5)
print 'stopping...'
pb.destroy()
ttk.Button(root, text="Run", command=foo).pack()
回答1:
Here the solution :
from Tkinter import *
import ttk
from time import sleep
root = Tk()
def foo():
print 'starting...'
pb = ttk.Progressbar(root, mode='indeterminate')
pb.pack()
root.update()
sleep(5)
print 'stopping...'
pb.destroy()
ttk.Button(root, text="Run", command=foo).pack()
root.mainloop()
Now the why : tkinter refresh it's GUI when there is available time between some function call. So if you want to make an interface that show the progress of a huge process you have to call periodically and manually the Tk.update() method.
In fact in your code you are doing a time.sleep(5), one can expect that Tkinter will update the GUI during the sleep, but this is an 'active' wait so the tkinter GUI is'nt refreshed.
Here comes a way to make the user aware that something is happening by moving the progress bar every 25ms. If no test about the 0.025 (or other reasonable value), the progress bar go mad and move too quickly. The idea is to not use sleep but time instead :
from Tkinter import *
import ttk
from time import *
root = Tk()
def foo():
print 'starting...'
pb = ttk.Progressbar(root, mode='indeterminate')
pb.pack()
root.update()
start = time()
last_update= time()
while (time() - start) <= 5:
current = time()
if (current-last_update)> 0.025:
pb.step()
root.update()
last_update = current
print 'stopping...'
pb.destroy()
ttk.Button(root, text="Run", command=foo).pack()
root.mainloop()
来源:https://stackoverflow.com/questions/26458894/tkinter-command-ignores-some-lines