I am writing an app in python using tkinter. In this app I am trying to send out a batch of emails and I want to show a progress bar while they are being sent. I am able to create the progress bar and start it, but when the emails are being sent, the bar just stops moving (If it is started way before the emails are sent, I want to start the bar just before the emails are sent, but it just hangs and nothing moves on the bar when I do it like this.
This is an old question but the code recipe I'm referring to has helped me with a similar concept, so I thought it should be shared.
This type of problem needs to use threading so that we spilt up the job of updating the GUI and doing the actual task (such as sending emails). Have a look at this code recipe from Active State, I believe it's exactly what you're looking for as an example of threading and passing information between threads (via a queue).
I try to highlight the important parts from the code recipe. I don't include setting up the progress bar itself but rather the overall code structure and getting/setting a queue.
import Tkinter import threading import Queue class GuiPart: def __init__(self, master, queue, endCommand): self.queue = queue # Do GUI set up here (i.e. draw progress bar) # This guy handles the queue contents def processIncoming(self): while self.queue.qsize(): try: # Get a value (email progress) from the queue progress = self.queue.get(0) # Update the progress bar here. except Queue.Empty: pass class ThreadedClient: # Launches the Gui and does the sending email task def __init__(self, master): self.master = master self.queue = Queue.Queue() # Set up the Gui, refer to code recipe self.gui = GuiPart(master, self.queue, ...) # Set up asynch thread (set flag to tell us we're running) self.running = 1 self.email_thread = threading.Thread(target = self.send_emails) self.email_thread.start() # Start checking the queue self.periodicCall() def periodicCall(self): # Checks contents of queue self.gui.processIncoming() # Wait X milliseconds, call this again... (see code recipe) def send_emails(self): # AKA "worker thread" while (self.running): # Send an email # Calculate the %age of email progress # Put this value in the queue! self.queue.put(value) # Eventually run out of emails to send. def endApplication(self): self.running = 0 root = Tkinter.Tk() client = ThreadedClient(root) root.mainloop()