Scrolling Progress Bar in Tkinter
have you tried ttk's determinate Progressbar? You can make the progress just continuously scroll across the bar.
for example:
#!/usr/bin/env python3import tkinterimport tkinter.ttk as ttkroot = tkinter.Tk()frame = ttk.Frame()pb = ttk.Progressbar(frame, length=300, mode='determinate')frame.pack()pb.pack()pb.start(25)root.mainloop()
I know its an old question, but I have found a way to do this for anyone else writing tkinter.
I've been working on a tkinter app for a bit now and have determined that to handle tkinter objects, you absolutely need a separate thread. Although it is apparently frowned upon to handle tkinter objects via something else than the mainloop()
method, it has been working well for me. I've never had a main thread is not in main loop
error and never experienced objects that didn't update correctly.
I edited Corey Goldberg's code a bit and got it working. Here's what I got (some explanations in the comments).
import tkinterimport tkinter.ttk as ttkimport threadingdef mainProgram(): # secure the main program initialization in its own def root = tkinter.Tk() frame = ttk.Frame() # You need to use indeterminate mode to achieve this pb = ttk.Progressbar(frame, length=300, mode='indeterminate') frame.pack() pb.pack() # Create a thread for monitoring loading bar # Note the passing of the loading bar as an argument barThread = threading.Thread(target=keepLooping, args=(pb,)) # set thread as daemon (thread will die if parent is killed) barThread.daemon=True # Start thread, could also use root.after(50, barThread.start()) if desired barThread.start() pb.start(25) root.mainloop()def keepLooping(bar): # Runs thread continuously (till parent dies due to daemon or is killed manually) while 1: """ Here's the tricky part. The loading bar's position (for any length) is between 0 and 100. Its position is calculated as position = value % 100. Resetting bar['value'] to 0 causes it to return to position 0, but naturally the bar would keep incrementing forever till it dies. It works, but is a bit unnatural. """ if bar['value']==100: bar.config(value=0) # could also set it as bar['value']=0 if __name__=='__main__': mainProgram()
I've added if __name__=='__main__':
because I feel it defines the scope a bit better.
As a side note I've found that running threads with while 1:
will crank my CPU at about 20-30% usage for that one thread in particular. It's easily solvable by importing time
and using time.sleep(0.05)
thereafter significantly lowering the CPU usage.
Tested on Win8.1, Python 3.5.0.