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()