I am creating a user interface and there are actions which take some time to complete.
The process fetches some data. I want to use that data in the Ui class.
To prevent the interface freezing I use have a worker object which I put in a separate thread and control using signals.
To get access to the data retrieved by the worker I pass the Ui object and have the worker update the content of the Ui classes data variable.
If I try to pass var directly and modify it in the worker thread, the content within the Ui class does not change. Why is this?
Code Example (This works):
from PyQt5 import QtCore
QtCore.Signal = QtCore.pyqtSignal
class threadController(QtCore.QObject):
fire = QtCore.Signal()
def __init__(self):
super().__init__()
class worker(QtCore.QObject):
finished = QtCore.Signal()
def __init__(self,ob):
super(worker,self).__init__()
self.ob = ob
def workerfunction(self):
self.ob.var = [1,2,3] #modify the variable
self.finished.emit()
class Ui():
def __init__(self):
self.thread1 = QtCore.QThread()
self.thread1.start()
self.var = [] #Create an empty variable
self.workerobj = worker(self)
self.workerobj.moveToThread(self.thread1)
self.threadControllerObj = threadController()
self.threadControllerObj.fire.connect(self.workerobj.workerfunction)
def startThreadProcess(self):
self.workerobj.finished.connect(self.check) #Need to make sure the thread has finished
self.threadControllerObj.fire.emit() #fire the worker function
def check(self):
print(self.var) #this runs when the worker function in the thread has finished
if __name__ == '__main__':
app = QtCore.QCoreApplication([])
UiObj = Ui()
UiObj.startThreadProcess()
QtCore.QTimer.singleShot(1000, app.quit)
app.exec_()
In addition to this, is this the correct way to go about gaining access to data produced in a worker function which is running in a separate thread?
Code Example (This does not work)
from PyQt5 import QtCore
QtCore.Signal = QtCore.pyqtSignal
class threadController(QtCore.QObject):
fire = QtCore.Signal()
def __init__(self):
super().__init__()
class worker(QtCore.QObject):
finished = QtCore.Signal()
def __init__(self,var):
super(worker,self).__init__()
self.var = var
def workerfunction(self):
self.var = [1,2,3]
self.finished.emit()
class container():
def __init__(self):
self.thread1 = QtCore.QThread()
self.thread1.start()
self.var = []
self.workerobj = worker(self.var)
self.workerobj.moveToThread(self.thread1)
self.threadControllerObj = threadController()
self.threadControllerObj.fire.connect(self.workerobj.workerfunction)
def startThreadProcess(self):
self.workerobj.finished.connect(self.check) #Need to make sure the thread has finished
self.threadControllerObj.fire.emit() #fire the worker function
def check(self):
print(self.var) #this runs when the worker function in the thread has finished
if __name__ == '__main__':
app = QtCore.QCoreApplication([])
contain = container()
contain.startThreadProcess()
QtCore.QTimer.singleShot(1000, app.quit)
app.exec_()