I'm trying to create a simple threaded application whereby i have a method which does some long processing and a widget that displays a loading bar and cancel button.
My problem is that no matter how i implement the threading it doesn't actually thread - the UI is locked up once the thread kicks in. I've read every tutorial and post about this and i'm now resorting on asking the community to try and solve my problem as i'm at a loss!
Initially i tried subclassing QThread until the internet said this was wrong. I then attempted the moveToThread approach but it made zero difference.
loadingThreadObject = LoadThread(arg1)
loadingThread = PythonThread()
PythonThread class (apparently QThreads are bugged in pyQt and don't start unless you do this):
class PythonThread (QtCore.QThread):
def __init__(self, parent=None):
class LoadThread (QtCore.QObject):
results = QtCore.Signal(tuple)
def __init__ (self, arg):
# Init QObject
# Store the argument
self.arg = arg
def load (self):
# Some heavy lifting is done
loaded = True
errors = 
# Emits the results
Any help is greatly appreciated!
The problem was with the SQL library I was using (a custom in-house solution) which turned out not to be thread safe and thus performed blocking queries.
If you are having a similar problem, first try removing the SQL calls and seeing if it still blocks. If that solves the blocking issue, try reintroducing your queries using raw SQL via
MySQLdb (or the equivalent for the type of DB you're using). This will diagnose whether or not the problem is with your choice of SQL library.
The function connected to the
started signal will run the thread which it was connected, the main GUI thread. However, a QThread's
start() function executes its
run() method in the thread after the thread is initialized so a subclass of QThread should be created and its run method should run
LoadThread.load, the function you want to execute. Don't inherit from PythonThread, there's no need for that. The QThread subclass's
start() method should be used to start the thread.
PS: Since in this case the subclass of QThread's
run() method only calls
run() method could be simply set to
class MyThread(QtCore.QThread): run = LoadThread.load # x = y in the class block sets the class's x variable to y
import time from PyQt4 import QtCore, QtGui import sys application = QtGui.QApplication(sys.argv) class LoadThread (QtCore.QObject): results = QtCore.pyqtSignal(tuple) def __init__ (self, arg): # Init QObject super(QtCore.QObject, self).__init__() # Store the argument self.arg = arg def load(self): # # Some heavy lifting is done # time.sleep(5) loaded = True errors =  # Emits the results self.results.emit((loaded, errors)) l = LoadThread("test") class MyThread(QtCore.QThread): run = l.load thread = MyThread() button = QtGui.QPushButton("Do 5 virtual push-ups") button.clicked.connect(thread.start) button.show() l.results.connect(lambda:button.setText("Phew! Push ups done")) application.exec_()