While some parts of the Qt framework are thread safe, much of it is not. The Qt C++ documentation provides a good overview of which classes are reentrant (can be used to instantiate objects in multiple threads). The following rules are the most widely sought:
QObject.moveToThread()if you need to move a Qt object from one thread to another (does not apply to Qt GUI objects which must always remain in the main thread). But note that the object must not have a parent.
As per this Stack Overflow QA, it is not recommended to use Python threads if your thread intends to interact with PyQt in any way (even if that part of the Qt framework is thread safe).
# this method can be anything and anywhere as long as it is accessible for connection @pyqtSlot() def run_on_complete(): pass # An object containing methods you want to run in a thread class Worker(QObject): complete = pyqtSignal() @pyqtSlot() def a_method_to_run_in_the_thread(self): # your code # Emit the complete signal self.complete.emit() # instantiate a QThread thread = QThread() # Instantiate the worker object worker = Worker() # Relocate the Worker object to the thread worker.moveToThread(thread) # Connect the 'started' signal of the QThread to the method you wish to run thread.started.connect(worker.a_method_to_run_in_the_thread) # connect to the 'complete' signal which the code in the Worker object emits at the end of the method you are running worker.complete.connect(run_on_complete) # start the thread (Which will emit the 'started' signal you have previously connected to) thread.start()