Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 3.x PyQt5+;Python3:将列表、dict作为信号参数跨线程传递_Python 3.x_Multithreading_Pyqt5_Thread Safety_Signals Slots - Fatal编程技术网

Python 3.x PyQt5+;Python3:将列表、dict作为信号参数跨线程传递

Python 3.x PyQt5+;Python3:将列表、dict作为信号参数跨线程传递,python-3.x,multithreading,pyqt5,thread-safety,signals-slots,Python 3.x,Multithreading,Pyqt5,Thread Safety,Signals Slots,我使用pyqtSignal将python列表作为参数从工作线程发送到主线程。qt何时创建作为参数传递的对象的副本。根据:qt应该复制对象。但是,在下面的示例中,主线程可以更改从另一个线程发送的列表的内容 import sys import time from PyQt5.QtCore import QThread, QObject, pyqtSlot, pyqtSignal from PyQt5.QtWidgets import QApplication class ClassProcessi

我使用pyqtSignal将python列表作为参数从工作线程发送到主线程。qt何时创建作为参数传递的对象的副本。根据:qt应该复制对象。但是,在下面的示例中,主线程可以更改从另一个线程发送的列表的内容

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()
输出:

[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]

有人能给我解释一下如何以线程安全的方式通过pyqtSignal传递列表吗。谢谢。

在使用信号在线程之间传递容器类型时,PyQt的行为与Qt不同

具体来说,没有自动转换[1]到等效的Qt类型,因此没有隐式复制。不过,PyQt确实提供了一种机制来显式请求此类转换。为此,您可以使用
QVariantList
QVariantMap
定义自定义信号:

    py_sig_send_data = pyqtSignal('QVariantList')
但是,需要注意的是,
QVariantMap
仅支持字符串键

不过,总而言之,在通过线程间的信号传递可变python类型之前,明确地复制它们可能更简单、更清晰、更安全


[1] 或者至少,.

有趣的是,没有更明确地说明这一点。我搜索了很多地方,但显然没有找到合适的地方。显式副本可能用于发送一次信号;复制到data_buffer和data_buffer的数据作为参数传递。连续发送(例如每秒50次)如何?发送线程和接收线程可能同时访问数据缓冲区。@John。如果你想避免复制,你就需要使用某种类型的。