PySide2 子线程发信号更新界面、生产者消费者模型

需求是这样的:主线程需要把一些耗时操作放在子线程中执行,子线程执行完毕后通知主线程更新 UI。但是子线程只有一个,且耗时操作必须一个一个来,不能并发执行。怎么让子线程挨个执行主线程下发的命令呢?

解决办法就是:主线程把需要执行的命令放在一个队列里,子线程不断去读取队列里的命令,然后挨个读取出来执行,执行完毕之后通知主线程更新 UI。在这里,主线程相当于生成者(生产命令),子线程相当于消费者(消费命令)。在这里,只有一个生产者和一个消费者,是最简单的生产者消费者模型。

我这里有个样例程序,点击发送就是向子线程发送命令,子线程获取到命令后就开始执行,然后发信号通知主线程更新 UI。
在这里插入图片描述
完整代码如下:

import datetime

from PySide2.QtCore import QThread, QObject, Signal, Slot
from PySide2.QtWidgets import QApplication, QInputDialog, QDialog, QLineEdit, QPushButton, QVBoxLayout, QLabel

import util


class MyInputDialog(QDialog):
    def __init__(self):
        super().__init__()

        #
        # 输入框
        #
        self.input = QLineEdit()


        #
        # label 标签
        #
        self.label_1 = QLabel()

        #
        # label_2
        #
        self.label_2 = QLabel()

        #
        # 发送按钮
        #
        self.ok_btn = QPushButton(text="发送")
        self.ok_btn.clicked.connect(self.submit)

        layout = QVBoxLayout()
        layout.addWidget(self.input)
        layout.addWidget(self.label_1)
        layout.addWidget(self.label_2)
        layout.addWidget(self.ok_btn)
        self.setLayout(layout)

    @Slot(str)
    def update_label1(self, result):
        self.label_1.setText("更新标签成功:" + result)

    @Slot(str)
    def update_label2(self, result):
        self.label_2.setText("更新标签成功:" + result)

    def submit(self):
        msg = self.input.text()
        message.append(msg)

class Worker(QThread):
    def __init__(self, parent):
        super().__init__()
        self.signals = Communicate()
        self.signals.label_singal.connect(parent.update_label1)
        self.signals.table_singal.connect(parent.update_label2)

    def run(self):
        while True:
            if len(message) != 0:
                msg = message.pop(0)
                if msg == "label_1":
                    self.get_label1()
                elif msg == "label_2":
                    self.get_label2()

    def get_label1(self):
        #
        # 模拟耗时操作,去获取数据
        #
        self.signals.label_singal.emit(get_time())

    def get_label2(self):
        self.signals.table_singal.emit(get_time())



class Communicate(QObject):
    label_singal = Signal(str)
    table_singal = Signal(str)

def get_time() -> str:
    """
    获取当前时间,返回时间字符串,如:2020-06-12 11:13:22
    :return:时间字符串
    """
    now_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    return now_time

#
# 消息队列,全局变量
#
message = []


if __name__ == '__main__':
    app = QApplication()


    #
    # 显示输入框
    #
    dial = MyInputDialog()
    dial.show()

    worker = Worker(dial)
    worker.start()


    app.exec_()
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值