如何从不同的进程向 GUI 中的槽发出信号?

2024-01-14

语境: 在 Python 中,主线程生成第二个进程(使用多处理模块),然后启动 GUI(使用 PyQt4)。此时主线程会阻塞,直到 GUI 关闭。第二个进程始终处于处理状态,理想情况下应以异步方式向 GUI 中的特定插槽发出信号。

问题: Python 和 PyQt4 中可以使用哪些方法/工具来实现这一目标以及如何实现?最好以软中断方式而不是轮询方式。

抽象地说,我能想到的解决方案是在主线程中实例化一个“工具/处理程序”,它从 GUI 实例中获取可用插槽,并与第二个进程中获取的信号连接,假设我向该工具提供了一些信息:预期或硬编码。这可以实例化为第三个进程/线程。


这是一个示例 Qt 应用程序,演示了从子进程向母进程中的槽发送信号。我不确定这是正确的方法,但它确实有效。

我将过程区分为mother and child,因为这个词parent已在 Qt 上下文中使用。
母进程有两个线程。母进程的主线程通过以下方式向子进程发送数据multiprocessing.Queue。子进程将处理后的数据和要发送到母进程的第二个线程的信号签名通过multiprocessing.Pipe。母进程的第二个线程实际上发出了信号。

Python 2.X、PyQt4:

from multiprocessing import Process, Queue, Pipe
from threading import Thread
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *

class Emitter(QObject, Thread):

    def __init__(self, transport, parent=None):
        QObject.__init__(self,parent)
        Thread.__init__(self)
        self.transport = transport

    def _emit(self, signature, args=None):
        if args:
            self.emit(SIGNAL(signature), args)
        else:
            self.emit(SIGNAL(signature))

    def run(self):
        while True:
            try:
                signature = self.transport.recv()
            except EOFError:
                break
            else:
                self._emit(*signature)

class Form(QDialog):

    def __init__(self, queue, emitter, parent=None):
        super(Form,self).__init__(parent)
        self.data_to_child = queue
        self.emitter = emitter
        self.emitter.daemon = True
        self.emitter.start()
        self.browser = QTextBrowser()
        self.lineedit = QLineEdit('Type text and press <Enter>')
        self.lineedit.selectAll()
        layout = QVBoxLayout()
        layout.addWidget(self.browser)
        layout.addWidget(self.lineedit)
        self.setLayout(layout)
        self.lineedit.setFocus()
        self.setWindowTitle('Upper')
        self.connect(self.lineedit,SIGNAL('returnPressed()'),self.to_child)
        self.connect(self.emitter,SIGNAL('data(PyQt_PyObject)'), self.updateUI)

    def to_child(self):
        self.data_to_child.put(unicode(self.lineedit.text()))
        self.lineedit.clear()

    def updateUI(self, text):
        text = text[0]
        self.browser.append(text)

class ChildProc(Process):

    def __init__(self, transport, queue, daemon=True):
        Process.__init__(self)
        self.daemon = daemon
        self.transport = transport
        self.data_from_mother = queue

    def emit_to_mother(self, signature, args=None):
        signature = (signature, )
        if args:
            signature += (args, )
        self.transport.send(signature)

    def run(self):
        while True:
            text = self.data_from_mother.get()
            self.emit_to_mother('data(PyQt_PyObject)', (text.upper(),))

if __name__ == '__main__':

    app = QApplication(sys.argv)
    mother_pipe, child_pipe = Pipe()
    queue = Queue()
    emitter = Emitter(mother_pipe)
    form = Form(queue, emitter)
    ChildProc(child_pipe, queue).start()
    form.show()
    app.exec_()

为了方便起见,还有 Python 3.X、PySide:

from multiprocessing import Process, Queue, Pipe
from threading import Thread

from PySide import QtGui, QtCore

class Emitter(QtCore.QObject, Thread):

    def __init__(self, transport, parent=None):
        QtCore.QObject.__init__(self, parent)
        Thread.__init__(self)
        self.transport = transport

    def _emit(self, signature, args=None):
        if args:
            self.emit(QtCore.SIGNAL(signature), args)
        else:
            self.emit(QtCore.SIGNAL(signature))

    def run(self):
        while True:
            try:
                signature = self.transport.recv()
            except EOFError:
                break
            else:
                self._emit(*signature)

class Form(QtGui.QDialog):

    def __init__(self, queue, emitter, parent=None):
        super().__init__(parent)
        self.data_to_child = queue
        self.emitter = emitter
        self.emitter.daemon = True
        self.emitter.start()
        self.browser = QtGui.QTextBrowser()
        self.lineedit = QtGui.QLineEdit('Type text and press <Enter>')
        self.lineedit.selectAll()
        layout = QtGui.QVBoxLayout()
        layout.addWidget(self.browser)
        layout.addWidget(self.lineedit)
        self.setLayout(layout)
        self.lineedit.setFocus()
        self.setWindowTitle('Upper')
        self.lineedit.returnPressed.connect(self.to_child)
        self.connect(self.emitter, QtCore.SIGNAL('data(PyObject)'), self.updateUI)

    def to_child(self):
        self.data_to_child.put(self.lineedit.text())
        self.lineedit.clear()

    def updateUI(self, text):
        self.browser.append(text[0])

class ChildProc(Process):

    def __init__(self, transport, queue, daemon=True):
        Process.__init__(self)
        self.daemon = daemon
        self.transport = transport
        self.data_from_mother = queue

    def emit_to_mother(self, signature, args=None):
        signature = (signature, )
        if args:
            signature += (args, )
        self.transport.send(signature)

    def run(self):
        while True:
            text = self.data_from_mother.get()
            self.emit_to_mother('data(PyQt_PyObject)', (text.upper(),))

if __name__ == '__main__':

    app = QApplication(sys.argv)
    mother_pipe, child_pipe = Pipe()
    queue = Queue()
    emitter = Emitter(mother_pipe)
    form = Form(queue, emitter)
    ChildProc(child_pipe, queue).start()
    form.show()
    app.exec_()
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何从不同的进程向 GUI 中的槽发出信号? 的相关文章

  • 使用 pythonbrew 编译 Python 3.2 和 2.7 时出现问题

    我正在尝试使用构建多个版本的 python蟒蛇酿造 http pypi python org pypi pythonbrew 0 7 3 但我遇到了一些测试失败 这是在运行的虚拟机上 Ubuntu 8 04 32 位 当我使用时会发生这种情
  • 没有名为 crypto.cipher 的模块

    我现在正在尝试加密一段时间 我最近得到了这个基于 python 的密码器 名为PythonCrypter https github com jbertman PythonCrypter 我对 Python 相当陌生 当我尝试通过终端打开 C
  • Django 代理模型的继承和多态性

    我正在开发一个我没有启动的 Django 项目 我面临着一个问题遗产 我有一个大模型 在示例中简化 称为MyModel这应该代表不同种类的物品 的所有实例对象MyModel应该具有相同的字段 但方法的行为根据项目类型的不同而有很大差异 到目
  • Python 的键盘中断不会中止 Rust 函数 (PyO3)

    我有一个使用 PyO3 用 Rust 编写的 Python 库 它涉及一些昂贵的计算 单个函数调用最多需要 10 分钟 从 Python 调用时如何中止执行 Ctrl C 好像只有执行结束后才会处理 所以本质上没什么用 最小可重现示例 Ca
  • 使 django 服务器可以在 LAN 中访问

    我已经安装了Django服务器 可以如下访问 http localhost 8000 get sms http 127 0 0 1 8000 get sms 假设我的IP是x x x x 当我这样做时 从同一网络下的另一台电脑 my ip
  • 为 Anaconda Python 安装 psycopg2

    我有 Anaconda Python 3 4 但是每当我运行旧代码时 我都会通过输入 source activate python2 切换到 Anaconda Python 2 7 我的问题是我为 Anaconda Python 3 4 安
  • Python(Selenium):如何通过登录重定向/组织登录登录网站

    我不是专业程序员 所以请原谅任何愚蠢的错误 我正在做一些研究 我正在尝试使用 Selenium 登录数据库来搜索大约 1000 个术语 我有两个问题 1 重定向到组织登录页面后如何使用 Selenium 登录 2 如何检索数据库 在我解决
  • 使用 on_bad_lines 将 pandas.read_csv 中的无效行写入文件

    我有一个 CSV 文件 我正在使用 Python 来解析该文件 我发现文件中的某些行具有不同的列数 001 Snow Jon 19801201 002 Crom Jake 19920103 003 Wise Frank 19880303 l
  • 根据列值突出显示数据框中的行?

    假设我有这样的数据框 col1 col2 col3 col4 0 A A 1 pass 2 1 A A 2 pass 4 2 A A 1 fail 4 3 A A 1 fail 5 4 A A 1 pass 3 5 A A 2 fail 2
  • 如何从网页中嵌入的 Tableau 图表中抓取工具提示值

    我试图弄清楚是否有一种方法以及如何使用 python 从网页中的 Tableau 嵌入图形中抓取工具提示值 以下是当用户将鼠标悬停在条形上时带有工具提示的图表示例 我从要从中抓取的原始网页中获取了此网址 https covid19 colo
  • 测试 python Counter 是否包含在另一个 Counter 中

    如何测试是否是pythonCounter https docs python org 2 library collections html collections Counter is 包含在另一个中使用以下定义 柜台a包含在计数器中b当且
  • Python pickle:腌制对象不等于源对象

    我认为这是预期的行为 但想检查一下 也许找出原因 因为我所做的研究结果是空白 我有一个函数可以提取数据 创建自定义类的新实例 然后将其附加到列表中 该类仅包含变量 然后 我使用协议 2 作为二进制文件将该列表腌制到文件中 稍后我重新运行脚本
  • 如何在Python中获取葡萄牙语字符?

    我正在研究葡萄牙语 角色看起来很奇怪 我怎样才能解决这个问题 代码 import feedparser import random Vou definir os feeds feeds conf feedurl http pplware s
  • Python 的“zip”内置函数的 Ruby 等价物是什么?

    Ruby 是否有与 Python 内置函数等效的东西zip功能 如果不是 做同样事情的简洁方法是什么 一些背景信息 当我试图找到一种干净的方法来进行涉及两个数组的检查时 出现了这个问题 如果我有zip 我可以写这样的东西 zip a b a
  • 如何使用Python创建历史时间线

    So I ve seen a few answers on here that helped a bit but my dataset is larger than the ones that have been answered prev
  • Pygame:有没有简单的方法可以找到按下的任何字母数字的字母/数字?

    我目前正在开发的游戏需要让人们以自己的名义在高分板上计时 我对如何处理按键有点熟悉 但我只处理过寻找特定的按键 有没有一种简单的方法可以按下任意键的字母 而不必执行以下操作 for event in pygame event get if
  • 无法在 Python 3 中导入 cProfile

    我试图将 cProfile 模块导入 Python 3 3 0 但出现以下错误 Traceback most recent call last File
  • 使用 \r 并打印一些文本后如何清除控制台中的一行?

    对于我当前的项目 有一些代码很慢并且我无法使其更快 为了获得一些关于已完成 必须完成多少的反馈 我创建了一个进度片段 您可以在下面看到 当你看到最后一行时 sys stdout write r100 80 n I use 80覆盖最终剩余的
  • 如何在Python中对类别进行加权随机抽样

    给定一个元组列表 其中每个元组都包含一个概率和一个项目 我想根据其概率对项目进行采样 例如 给出列表 3 a 4 b 3 c 我想在 40 的时间内对 b 进行采样 在 python 中执行此操作的规范方法是什么 我查看了 random 模
  • 将图像分割成多个网格

    我使用下面的代码将图像分割成网格的 20 个相等的部分 import cv2 im cv2 imread apple jpg im cv2 resize im 1000 500 imgwidth im shape 0 imgheight i

随机推荐

  • Yii2:活动记录列别名

    我正在使用 Yii2 框架和高级模板 我的控制器文件中的列别名出现问题 这是我的代码 models new ActiveDataProvider query gt User find gt select member gt fullname
  • 使用 Python 删除 json 文件中的新换行符。

    我正在从 firebase 下载数据 并将其导出为 json 之后 我尝试将其上传到bigquery 但我需要删除新的换行符以供大查询接受它 ConnectionTime 730669 644775033 objectId eHFvTUNq
  • Flex-direction:column 不允许子项在 Firefox 中滚动[重复]

    这个问题在这里已经有答案了 我正在对元素使用显示柔性 outer 应根据内容调整其高度 但不得超过特定高度 例如100px 一旦超过高度 我希望里面的内容开始垂直滚动 此行为在 Chrome 上按预期工作 但在 Firefox 中内容包装器
  • 带有服务帐户令牌的 Kubernetes kubeconfig

    我有一个调用的脚本kubectl server server certificate authority ca token token get pod all namespaces簇外 其中 token来自服务帐户my sa 在命名空间中m
  • 使用 Android APK 2.2 打开硬件加速(如果可用)(例如 Android 3+)

    我为Android 3 0开发了一个应用程序 它运行得很好 但客户端坚持兼容2 2设备 禁用硬件加速 使用 Android 兼容包 NIO 向后移植支持 对于任务和执行程序 以及 View 方法的一些重新实现 我能够将我的应用程序移植到 A
  • 如何使用其他端口在 Visual Studio Code 中离线调试无服务器?

    我有两个无服务器离线 服务器 我需要同时在本地运行 所以我需要更改其中一台服务器的端口 我使用 Visual Studio Code 调试器运行服务器 服务器的配置位于 launch json 文件中 如何更改无服务器离线应用程序的端口 以
  • android.app.Application 子类,onTerminate 未被调用

    从文档中android app Application 那些需要维护全局应用程序状态的基类 我正在使用自己的子类来维护一个用于查询服务器的对象 还来自文档 onTerminate 当应用程序停止时调用 然而 onTerminate 在我的班
  • Entity Framework Core 2.0 删除记录而不是更新记录

    我认为这可能是一个错误 但我认为我可能缺少一些可以解释该行为的东西 任何帮助 将不胜感激 Technical details EF Core version Microsoft EntityFrameworkCore 2 0 1 Datab
  • 工厂女孩什么时候在数据库中创建对象?

    我正在尝试使用模拟会话FactoryGirl shoulda 它可以与固定装置配合使用 但我在使用工厂时遇到问题 我有以下工厂 用户登录名和电子邮件都有unique验证 Factory define user do u u login qu
  • 将多种内容类型发布到 Web api

    我有一个 Web api 我想发布一个图像文件 一些数据 以便在服务器收到它时正确处理它 调用代码看起来像这样 using var client new HttpClient using var content new MultipartF
  • java nio 否定 glob 模式

    fileSystem getPathMatcher glob pattern matches path getFileName 我想匹配所有不匹配 ts 的内容 java 中 glob 的语法是什么 在有人建议我使用正则表达式之前 我需要使
  • 将现有私钥导入 BKS Keystore

    我有一个由 openssl 按以下方式生成的密钥对 openssl genrsa out private key pem 2048 我将其转换为 DER 格式如下 openssl pkcs8 topk8 inform PEM outform
  • 使用 BroadcastReceiver 关闭 Activity

    我的应用程序中有一个活动 Main java 打开 我想使用广播接收器关闭该活动 如何关闭该活动 首先 您的 Main java 需要注册为接收器 您可以在 Main java 的 onResume 中注册它 Override public
  • 将网站图标添加到网站[重复]

    这个问题在这里已经有答案了 可能的重复 HTML 标题图像 https stackoverflow com questions 3103490 html title image 有人可以告诉我如何让图标出现在 PHP 的浏览器选项卡上吗 我
  • 应用商店提交错误无效的捆绑结构

    当我尝试提交之前成功提交的应用程序版本升级时 我从 XCode 8 1 收到以下错误 错误 ITMS 90171 无效的捆绑包结构 不允许使用二进制文件 Particle app Particle armv7 除了受支持捆绑包的 CFBun
  • 如何在用户键入时获取 JTextField 内容的长度?

    JTextField 有一个 keyTyped 事件 但似乎在它触发时单元格的内容尚未更改 因此 如果在这里阅读 length 总是错误的 必须有一种简单的方法来获取用户在击键后显示的长度 这可能不是最佳方式 并且已经有一段时间了 但在过去
  • 单击 div 外部 - 当 div 具有触发事件的按钮时 - angularjs

    我使用以下指令来检测何时在 div 外部进行点击 app directive clickOut function window parse return restrict A link function scope element attr
  • 其他属性的 Maven 密码加密

    我想使用 Maven 的密码加密 例如它用于 Mojo 属性的节点 我尝试将加密密码粘贴到 mojo 的正确属性中 但它将其视为纯文本 我曾是hoping我可以在 Mojo 属性的注释上设置一个属性 该属性可以解释它可以被加密 如果可以 则
  • 如何从 C# 更新文件的更改时间?

    文件可以有更改日期 该日期与上次修改日期或上次访问日期不同 更改日期通过 UI 或 NET API 不可见 有两个 Win32 函数通过HandleEx获取文件信息 http msdn microsoft com en us library
  • 如何从不同的进程向 GUI 中的槽发出信号?

    语境 在 Python 中 主线程生成第二个进程 使用多处理模块 然后启动 GUI 使用 PyQt4 此时主线程会阻塞 直到 GUI 关闭 第二个进程始终处于处理状态 理想情况下应以异步方式向 GUI 中的特定插槽发出信号 问题 Pytho