PyQt5 + Python 3:跨线程传递列表、字典作为信号参数

2024-03-07

我正在使用 pyqtSignal 将 python 列表作为参数从工作线程发送到主线程。 qt 何时创建作为参数传递的对象的副本。根据:http://www.embeddeduse.com/2013/06/29/copied-or-not-copied-arguments-signals-slots/ http://www.embeddeduse.com/2013/06/29/copied-or-not-copied-arguments-signals-slots/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 or QVariantMap:

    py_sig_send_data = pyqtSignal('QVariantList')

然而,重要的是要注意QVariantMap仅支持字符串键。

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

[1] 或者至少,不再 http://pyqt.sourceforge.net/Docs/PyQt4/incompatibilities.html#pyqt4-v4-7-4.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PyQt5 + Python 3:跨线程传递列表、字典作为信号参数 的相关文章

  • 如何使信号量超时

    Go 中的信号量是通过通道来实现的 一个例子是这样的 https sites google com site gopatterns concurrency semaphores https sites google com site gop
  • QDataWidgetMapper;将 TableWidget 映射到模型

    我没有找到任何文档显示 QDataWidgetMapper 实际上适用于哪些小部件 也没有找到任何使用 QTableWidget 进行映射的实现 它绝对适用于 QLineEdit 和 QComboBoxes 它们是输入小部件 但是是否可以映
  • 线程睡眠和Windows服务

    我正在开发一个 Windows 服务 该服务存在一些问题Thread Sleep 所以我想我会尝试使用计时器 因为这个问题建议 在 Windows 服务中使用 Thread Sleep https stackoverflow com que
  • 调用线程无法访问该对象,因为另一个线程拥有它

    我已经阅读了很多关于此错误的帖子 但我不明白如何在我的解决方案中解决它 我有一个进度条对话框 其中包含一些逻辑 通过按钮单击从 MainFrame 调用 void OnBtnClick object sender RoutedEventAr
  • FTP 下载冻结整个应用程序

    我正在尝试从 FTP 服务器下载一个大约 100 MB 的文件 这是一个测试 bin 文件 因为我正在测试该应用程序 我猜我将来想要下载的文件会更重 当我想下载文件时 整个应用程序就会冻结 几秒钟后它就会下载文件 该文件已完成 并且已成功下
  • ThreadPool.SetMinThreads 不创建任何新线程

    我想弄清楚到底有什么影响ThreadPool SetMinThreads makes 根据官方文档 https learn microsoft com en us dotnet api system threading threadpool
  • str.translate 与 str.replace - 何时使用哪一个?

    何时以及为什么使用前者而不是后者 反之亦然 目前尚不完全清楚为什么有些人使用前者以及为什么有些人使用后者 它们有不同的目的 translate只能用任意字符串替换单个字符 但一次调用可以执行多次替换 它的参数是一个特殊的表 它将单个字符映射
  • 无法在 virtualenv 中安装 libxml2

    我有一个问题libxml2蟒蛇模块 我正在尝试将其安装在python3 虚拟环境使用以下命令 pip install libxml2 python3 但它显示以下错误 Collecting libxml2 python3 Using cac
  • PHP Intl 扩展线程安全吗?

    我一直在阅读有关 PHP 中的语言环境的内容 看起来setlocale 线程有问题 我对线程不太熟悉 文档提到它不是线程安全的 我想让我的项目能够处理某些数字格式 并且 Intl 扩展似乎很有趣 http php net manual en
  • 使用 Python 绘制 USGS 水文数据甘特图?

    我编译了一个数据帧 其中包含几个不同流计的 USGS 流数据 现在我想创建一个类似的甘特图this https stackoverflow com questions 31820578 how to plot stacked event d
  • 使 Guid 属性成为线程安全的

    我的一个类有一个 Guid 类型的属性 该属性可以由多个线程同时读写 我的印象是对 Guid 的读取和写入不是原子的 因此我应该锁定它们 我选择这样做 public Guid TestKey get lock testKeyLock ret
  • 如何同时接受int和float类型的输入?

    我正在制作一个货币转换器 如何让 python 同时接受整数和浮点数 我就是这样做的 def aud brl amount From to ER 0 42108 if amount int if From strip aud and to
  • 没有名为“PIL”的模块

    当我尝试时遇到错误 from PIL import Image ImageFilter 在 Python 文件中我收到一条错误消息ModuleNotFoundError No module named PIL 到目前为止 我已经尝试卸载 重
  • 类型错误:描述符“__weakref__”不适用于父级 __str__ 方法中的对象

    我有一个父类 我们称之为A还有一堆儿童班 B C D等等 我想定义一个 str 父类及其内部的方法我想通过访问子类的成员dir self 它有效 但是当我检查该名称是否可调用时callable getattr self attr I get
  • Python中Decimal类型的澄清

    每个人都知道 或者至少 每个程序员都应该知道 http docs oracle com cd E19957 01 806 3568 ncg goldberg html 即使用float类型可能会导致精度错误 然而 在某些情况下 精确的解决方
  • 在java中实现你自己的阻塞队列

    我知道这个问题之前已经被问过并回答过很多次了 但我只是无法根据互联网上找到的示例找出窍门 例如this http tutorials jenkov com java concurrency blocking queues html or t
  • 如何创建一个语句来打印以特定单词开头的单词? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 如何在 python 中打印从特定字母开始的单词 而不使用函数 而是使用方法或循环 1 我有一个字符串 想要打印以 m 开头的单词 S
  • 为什么libc++的shared_ptr实现使用完整内存屏障而不是宽松内存屏障?

    在boost的实现中shared ptr 它用放松内存排序以增加其引用计数 https github com boostorg smart ptr blob master include boost smart ptr detail sp
  • 任务并行库周围是否有一个接口包装器,以便我可以将其交换用于单元测试?

    I asked 这个问题 https stackoverflow com questions 3362734 unit testing concurrent software what do you do不久以前 我现在知道这是一个坏主意
  • C++ 异步线程同时运行

    我是 C 11 中线程的新手 我有两个线程 我想让它们同时启动 我可以想到两种方法 如下 然而 似乎它们都没有按照我的预期工作 他们在启动另一个线程之前启动一个线程 任何提示将不胜感激 另一个问题是我正在研究线程队列 所以我会有两个消费者和

随机推荐