I am using pyqtSignal to send a python list as an argument from worker thread to main thread. When does qt create a copy of the object being passed as argument. According to: http://www.embeddeduse.com/2013/06/29/copied-or-not-copied-arguments-signals-slots/ the qt should make a copy of the object. However, in the example below the main thread can change the contents of the list being sent from another thread.
import sys
import time
from PyQt5.QtCore import QThread, QObject, pyqtSlot, pyqtSignal
from PyQt5.QtWidgets import QApplication
class ClassProcessing(QObject):
py_sig_send_data = pyqtSignal(list)
def __init__(self):
super().__init__()
# initialize some variables
self.data = [1, 2, 3, 4, 5]
def worker(self):
print(self.data)
self.py_sig_send_data.emit(self.data)
time.sleep(1)
print("modfied data in thread", self.data)
class ClassProcessingThread(QObject):
def __init__(self):
super().__init__()
self.objThread = QThread()
self.objThread_id = 1
self.objThread_finished = False
self.processing = ClassProcessing()
self.processing.moveToThread(self.objThread)
self.objThread.started.connect(self.processing.worker)
self.objThread.start()
class SomeClass(QObject):
def __init__(self):
super().__init__()
@pyqtSlot(list)
def receive_data(self, data):
print("received data", data)
data[1] = 42
print("modified data", data)
def main():
app = QApplication(sys.argv)
processing_thread = ClassProcessingThread()
some_class = SomeClass()
processing_thread.processing.py_sig_send_data.
connect(some_class.receive_data)
sys.exit(app.exec_())
if __name__ == '__main__':
main()
The output:
[1, 2, 3, 4, 5]
received data [1, 2, 3, 4, 5]
modified data [1, 42, 3, 4, 5]
modified data in thread [1, 42, 3, 4, 5]
Can someone please explain to me how to pass a list in a pyqtSignal in a thread-safe manner. Thanks.