Run thread from Tkinter and wait until it's finished Run thread from Tkinter and wait until it's finished tkinter tkinter

Run thread from Tkinter and wait until it's finished


To prevent the GUI from freezing you need self.run() to end quickly.It needs to spawn a thread, start the thread, then end:

import Queuesentinel = object()root = tkinter.Tk()...def run(self, url):    outqueue = Queue.Queue()    thr = threading.Thread(target=self.run_tests, args=(url, outqueue))    thr.start()    root.after(250, self.update, outqueue)

Now the function this thread runs can run for a long time:

def run_tests(self, url, outqueue):    outqueue.put("Running test #1...")    self.webtester.urlopen(url)    outqueue.put("Running test #2")            self.webtester.test2()    outqueue.put(sentinel)

But because Tkinter expects all GUI calls to originate from a single thread, this spawned thread must not make any GUI calls. For it to interact with the GUI, you can send output (such as a status update message) through a Queue.Queue and concurrently let the main Tkinter thread monitor this Queue.Queue periodically (through calls to root.after):

def update(self, outqueue):    try:        msg = outqueue.get_nowait()        if msg is not sentinel:            self.appendLine(msg)            root.after(250, self.update, outqueue)        else:            # By not calling root.after here, we allow update to            # truly end            pass    except Queue.Empty:        root.after(250, self.update, outqueue)