How to properly terminate a QThread from a GUI application?
From the Qt documentation for QThread::terminate:
Warning: This function is dangerous and its use is discouraged. The thread can be terminated at any point in its code path. Threads can be terminated while modifying data. There is no chance for the thread to clean up after itself, unlock any held mutexes, etc. In short, use this function only if absolutely necessary.
It's probably a much better idea to re-think your threading strategy such that you can e.g. use QThread::quit() to signal the thread to quit cleanly, rather than trying to get the thread to terminate this way. Actually calling thread.exit() from within the thread should do that depending on how you have implemented run(). If you'd like to share the code for your thread run method that might hint as to why it doesn't work.
Bo Milanovich
I mostly deal with Python and its Qt bindings (PyQt and PySide for the most part) and web frameworks, but you'll see me poking around JavaScript, C#, and ASP.NET forums as well. Check out my Pluralsight course on developing desktop applications using Python and Qt - http://www.pluralsight.com/courses/python-desktop-application-development
Updated on June 25, 2022Comments
-
Bo Milanovich about 2 years
I tried using
self.terminate()
in the QThread class, and alsoself.thread.terminate()
in the GUI class. I also tried puttingself.wait()
in both cases. However, there are two scenarios that happen:1) The thread does not terminate at all, and the GUI freezes waiting for the thread to finish. Once the thread finished, the GUI unfreezes and everything is back to normal.
2) The thread indeed does terminate, but at the same time it freezes the entire application.
I also tried using
self.thread.exit()
. No joy.To further clarify, I am trying to implement a user-abort button in GUI which would terminate the executing of the thread at any point in time.
Thanks in advance.
EDIT:
Here is the
run()
method:def run(self): if self.create: print "calling create f" self.emit(SIGNAL("disableCreate(bool)")) self.create(self.password, self.email) self.stop() self.emit(SIGNAL("finished(bool)"), self.completed) def stop(self): #Tried the following, one by one (and all together too, I was desperate): self.terminate() self.quit() self.exit() self.stopped = True self.terminated = True #Neither works
And here is the GUI class' method for aborting the thread:
def on_abort_clicked(self): self.thread = threadmodule.Thread() #Tried the following, also one by one and altogether: self.thread.exit() self.thread.wait() self.thread.quit() self.thread.terminate() #Again, none work
-
docsteer over 12 yearsHmm. And I assume the
self.create()
method is the time-consuming method in the thread? Generally what you would do in there is something likewhile not self.terminated() { do slow operation parts.. }
. Unfortunately I don't know Python well, but looks like there is a threading tutorial here that might help -
Bo Milanovich over 12 yearsI tried that as well. It happened to work somewhat (the GUI wouldn't freeze, but the thread would not terminate either). However the oddest thing just happened. I deleted all the
def stop(self)
code in the thread and thedef on_abort_clicked(self)
code in the GUI, and rewrote it. I simply putself.terminate()
in the thread'sstop()
function and didself.thread.stop()
in the GUI class. It works like a charm. AFAIK, that's the first thing I tried, and it didn't work before. I probably missed something.