Tkinter: stopping a background thread on demand

coldpizza vriolk at gmail.com
Thu Feb 19 23:20:14 CET 2009


I am writing a Tk GUI for a console script. I start a background
thread and pass it a callback function which writes debug info to a
Text widget in the main Tk loop.

I tried to find what is the established way to cleanly abort a child
thread when the user clicks the Stop button, but apparently Python
does not allow the parent process to explicitly stop a child thread.
Also I could not figure out how a parent can send a signal for a child
to stop and let it cleanup and exit cleanly.

I finally figured out a solution which was to set a 'TERMINATE' flag
on the `func_dict` property of the callback function, and then check
for the flag in the child module, but I still have doubts that this is
the proper way to do this sort of thing.

This works fine but it looks more like a dirty hack to me so my
question is: what is the proper way to send a signal to a child thread
to gracefully terminate, assuming the user decided to cancel an
operation?

from Tkinter import *
import threading

root = Tk()

class ConverterThread(threading.Thread):
    def __init__(self, source, target, callbackFunc):
        threading.Thread.__init__(self, name='converterThread')
        self.infile = srcName
        self.outfile = destName
        self.callbackFunc = callbackFunc
    def run(self):
        import myconverter
        myconverter.convert(self.infile, self.outfile,
self.callbackFunc)

def stopConversion(event=None):
    global job
    if (job and job.isAlive()):
        callbackFunc.func_dict['TERMINATE'] = True
        job = None

def updateLogCallback(data=None):
        log.insert(END, str(data))
        log.see('end')

job = ConverterThread(src='file1', dest='file2, updateLogCallback)
job.start()

stopBtn = Button(root, text="Stop", command=stopConversion)
stopBtn.pack()
log = Text(root)
root.mainloop()


And the callbackFunc in myConverter.py looks like this:

def printCallback(data):
    if (callback):
        callback(data)
        if callback.func_dict['TERMINATE'] == True:
            clean_up()
            sys.exit()
    else:
        print data





More information about the Python-list mailing list