pyqt5调用多线程以及QDialog弹窗处理数据

目录

方法一:

方法二:


方法一:

有一个应用场景,pyqt5执行过程中,启动一个QThread执行耗时操作,QThread执行过程中,会生成数据,生成的数据需要实时展示,这时候主程序在收到数据后,会调用QDialog实时展示,需要将数据由QThread传递到QDialog中,QDialog是一个单独的模块供主程序调用,在调用时,需要先启动QDialog,然后再调用QThread,下面是一个示例:

思路:

1. QThread中定义一个信号,QThread调用逻辑函数时,将自己定义的信号传递进去,由逻辑函数使用该信号发送产生的数据;

2. 主程序实例化QThread,并将QThread的信号与槽函数绑定;

3. 主程序定义一个跟QThread信号相同的信号,启动QDialog,并与QDialog中的函数中的槽函数进行绑定,这样主程序发送的信号就会由QDialog中的函数处理;

4. 在步骤2中QThread绑定的槽函数主要是接收QThread信号产生的数据,并由主函数创建的相同类型的信号发送出去,再有QDialog对象中的函数处理。

import sys
import time

from PyQt5.QtCore import pyqtSignal, QThread, Qt
from PyQt5.QtWidgets import QDialog, QPushButton, QHBoxLayout, QApplication, QVBoxLayout, QMainWindow, QWidget


# 实际执行的逻辑程序,被thread程序调用
class AA():
    # test_signal = pyqtSignal(str, list)
    def __init__(self, signal_trig):
        self.test_signal = signal_trig  # 接收Thread传递进来的信号
        self.hello()

    # 写逻辑函数
    def hello(self):
        for x in range(20):
            self.test_signal.emit(f'我是AA类{x}', list(range(10)))     # 使用Thread信号发送生成的数据
            time.sleep(2)


# 多线程函数--->被主程序调用
class My_thread(QThread):
    thread_trig = pyqtSignal(str, list)
    def __init__(self):
        super(My_thread, self).__init__()

    def run(self):
        a = AA(self.thread_trig)      # 将接收的信号传给调用的程序



# 主程序调用QDialog弹窗,Dialog弹窗会实时处理数据
class My_Dialog_test_signal(QDialog):
    # dialog_trig = pyqtSignal(str, list)
    def __init__(self, parent=None):
        super(My_Dialog_test_signal, self).__init__(parent)
        self.initUi()
        # self.dialog_trig.connect(self.trig_func)

    def initUi(self):
        vLayout = QVBoxLayout()
        btn = QPushButton('QDialog测试按钮')
        vLayout.addWidget(btn)
        self.setLayout(vLayout)
        self.resize(200, 200)
        self.show()

    def trig_func(self, ss, lst):
        print(ss, lst)


# 主界面程序
class CC(QWidget):
    trig = pyqtSignal(str, list)
    def __init__(self):
        super(CC, self).__init__()
        self.initUi()


    def initUi(self):
        btn = QPushButton('单击接收信号')
        self.resize(300, 300)
        hLayout = QHBoxLayout()
        hLayout.addWidget(btn)
        self.setLayout(hLayout)

        btn2 = QPushButton('测试弹窗信号')
        hLayout.addWidget(btn2)

        btn.clicked.connect(self.btn_click)
        btn2.clicked.connect(self.test_threadSignal)

    # 点击按钮调用Thread
    def btn_click(self):
        # self.t = My_thread(self.trig)
        self.t = My_thread()        # 传给My_thread
        self.t.thread_trig.connect(self.cc_print)   # 将Thread中的信号绑定槽函数
        self.t.start()


    def test_threadSignal(self):
        tmp = My_Dialog_test_signal(self)
        self.trig.connect(tmp.trig_func)    # 将主程序的信号绑定弹窗QDialog中的函数

    # 接收Thread信号发出来的值,并由主程序中的信号再次发送出去,由Dialog中的程序处理
    def cc_print(self, ss, lst):
        self.trig.emit(ss, lst)



if __name__ == '__main__':
    # PyQt5高清屏幕自适应设置,以及让添加的高清图标显示清晰,不然designer导入的图标在程序加载时会特别模糊
    QApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
    QApplication.setAttribute(Qt.AA_UseHighDpiPixmaps)
    app = QApplication(sys.argv)
    main_win = CC()

    main_win.show()
    sys.exit(app.exec_())

方法二:

1. 在QDialog中定义一个信号,并在其内部绑定槽函数;

2. 主程序调用QDialog窗口,并获取其信号;

3. 主程序调用QThread,并将步骤二中获取的信号,传给QThread;

4. thread调用实际的逻辑处理函数,并将主程序传递进来的信号,传递给逻辑函数;

5. 逻辑函数使用该信号发送数据;

import sys
import time

from PyQt5.QtCore import pyqtSignal, QThread, Qt
from PyQt5.QtWidgets import QDialog, QPushButton, QHBoxLayout, QApplication, QVBoxLayout, QMainWindow, QWidget


# 实际执行的逻辑程序,被thread程序调用
class AA():
    # test_signal = pyqtSignal(str, list)
    def __init__(self, signal_trig):
        self.test_signal = signal_trig  # 接收Thread传递进来的信号,实际为QDialog中定义的信号
        self.hello()

    # 写逻辑函数
    def hello(self):
        for x in range(20):
            self.test_signal.emit(f'我是AA类{x}', list(range(10)))     # 使用QDialog信号发送数据,会直接被dialog自己的程序处理
            time.sleep(2)


# 多线程函数--->被主程序调用
class My_thread(QThread):
    def __init__(self, trig):
        super(My_thread, self).__init__()
        self.trig = trig       # 获取主程序传递进来的dialog中的信号

    def run(self):
        a = AA(self.trig)      # 将dialog信号传递给实际执行的逻辑函数



# 主程序调用QDialog弹窗,Dialog弹窗会实时处理数据
class My_Dialog_test_signal(QDialog):
    dialog_trig = pyqtSignal(str, list)     # 只在dialog中定义信号
    def __init__(self, parent=None):
        super(My_Dialog_test_signal, self).__init__(parent)
        self.initUi()
        self.dialog_trig.connect(self.trig_func)    # dialog内部处理自己信号发出的值

    def initUi(self):
        vLayout = QVBoxLayout()
        btn = QPushButton('QDialog测试按钮')
        vLayout.addWidget(btn)
        self.setLayout(vLayout)
        self.resize(200, 200)
        self.show()

    # dialog_trig发出的信号处理函数
    def trig_func(self, ss, lst):
        print(ss, lst)


# 主界面程序
class CC(QWidget):
    def __init__(self):
        super(CC, self).__init__()
        self.initUi()


    def initUi(self):
        btn = QPushButton('单击接收信号')
        self.resize(300, 300)
        hLayout = QHBoxLayout()
        hLayout.addWidget(btn)
        self.setLayout(hLayout)

        btn2 = QPushButton('测试弹窗信号')
        hLayout.addWidget(btn2)

        btn.clicked.connect(self.btn_click)
        btn2.clicked.connect(self.test_threadSignal)

    # 点击按钮调用Thread
    def btn_click(self):
        self.t = My_thread(self.mgs_trig)  # 将dialog中的信号传递给QThread
        self.t.start()

    # 点击按钮,调用Dialog窗口
    def test_threadSignal(self):
        tmp = My_Dialog_test_signal(self)
        self.mgs_trig = tmp.dialog_trig    # 获取dialog对象中的信号

    # 接收Thread信号发出来的值,并由主程序中的信号再次发送出去,由Dialog中的程序处理
    def cc_print(self, ss, lst):
        self.trig.emit(ss, lst)



if __name__ == '__main__':
    # PyQt5高清屏幕自适应设置,以及让添加的高清图标显示清晰,不然designer导入的图标在程序加载时会特别模糊
    QApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
    QApplication.setAttribute(Qt.AA_UseHighDpiPixmaps)
    app = QApplication(sys.argv)
    main_win = CC()

    main_win.show()
    sys.exit(app.exec_())

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值