关于PyQT5进程间使用pyqtSignal

本文探讨了PyQtSignal在不同进程间通信的局限性,介绍了一种利用multiprocessing.Queue实现进程间消息传递的方法,通过具体代码示例展示了如何在多进程中实时更新GUI界面。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近一个项目中想要使用pyqtSignal实时在窗口中append另外一个进程中接收到的信号,但是试了好几次,都无法接收到emit信号,并且用id(signal)发现所有signal实例都是同一个。这就很奇怪了。
搜索后发现,原来是因为pyqt的signal只能够在同一个进程的不同线程中进行传递,而跨进程就不行,需要用到进程间通信,如队列,才能解决。
参考:https://www.v2ex.com/t/346882
没办法,只能暂时放弃这个想法了,毕竟对进程间通信还是很陌生


2020-03-02更新

经过几天的摸索,已经能够使用mutiprocessing.Queue进行进程间消息队列

from PyQt5.QtCore import QThread, pyqtSignal
from module.ui import * 
import multiprocessing

class readThread(QThread):

    def __init__(self, q, sig):
        super(readThread, self).__init__()
        self.q = q
        self.sig = sig

    def run(self):
        while True:
            if not self.q.empty():
                value = self.q.get(True)
                self.sig.emit(value)
            self.sleep(1)

class MyForm(QtWidgets.QMainWindow):
    sig = pyqtSignal(dict)
    def __init__(self):
        super().__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
		
		self.ui.startSyncButton.clicked.connect(self.start_sync)
		
        self.sig.connect(self.display_log)

        self.q = multiprocessing.Queue()

        self.read_thread = readThread(self.q, self.sig)
        
    def start_sync(self):
        # 为flask开启进程
        self.process = syncClass(self.q)
        self.process.start()
        # 为log显示开启线程
        self.read_thread.start()

    def display_log(self, log):
        # 添加tableWidget中展示数据
        numRows = self.ui.tableWidget.rowCount()
        self.ui.tableWidget.insertRow(numRows)
        for key, value in log.items():
            column_name = self.translate[key]
            column_num  = self.num[column_name]
            self.ui.tableWidget.setItem(numRows, int(column_num), QTableWidgetItem(str(value)))

class syncClass(multiprocessing.Process):
    def __init__(self, q):
        multiprocessing.Process.__init__(self)
        self.exit = multiprocessing.Event()
        self.q = q
    
    def run(self):
        simple_page = server.construct_blueprint(self.q)
        app = Flask(__name__)
        app.register_blueprint(simple_page)
        app.run(host="0.0.0.0",port=3100)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    app.setQuitOnLastWindowClosed(True)
    w = MyForm()
    app.setWindowIcon(QIcon("icon/logo.png"))
    app.aboutToQuit.connect(w.close_connection)
    # 设置最大显示
    w.showMaximized()
    w.show()
    sys.exit(app.exec_())

上面的代码只是一个简单的框架,并不能执行,其实现的流程为:

  1. 初始化界面、生成sig信号实例、生成q队列实例、生成read_thread读线程实例并传入q和sig;
  2. 点击startSyncButton,进入start_sync函数中,并传入q队列实例;
  3. start_sync函数实现:
    1. 实例化process并start process进程,该进程实现监听端口,如果有请求传入,就向队列q中put解析后的消息;
    2. start read_thread线程,该线程实现周期循环读队列q,如果有新消息,就emit信号;
  4. sig收到信号后连接槽函数display_log,该函数实现将消息输出到tableWidget中。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值