欢迎访问宙启技术站
智能推送

python之线程通过信号pyqtSignal刷新ui的方法

发布时间:2023-05-16 06:58:38

在Python中,使用多线程可以实现并发执行任务,这在处理大量任务时是非常有帮助的。但是,在多线程处理中,当需要更新界面以显示当前任务的进度或者完成情况时,就会出现一个问题:由于UI更新必须在主线程中进行,因此更新UI的代码必须在主线程中执行。

为了解决这个问题,Python提供了一种名为PyQtSignal的机制。PyQtSignal是一种用于在多个Python线程之间传递信号和数据的机制,它允许不同线程之间异步通信。一般情况下,PyQtSignal用于在线程间传递信号以更新UI。

1. 使用PyQtSignal来刷新UI

PyQtSignal是PyQt模块中提供的一种信号槽机制,PyQtSignal将信号(Signal)和槽(Slot)连接起来,实现线程之间的通信。这里我们主要关注如何在多线程程序中刷新UI,以下是使用PyQtSignal来刷新UI的代码示例:

# -*- coding:utf-8 -*-

from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QGridLayout, QPushButton, QLabel

from PyQt5.QtCore import pyqtSignal, QThread

import time

class WorkThread(QThread):

    change_value_signal = pyqtSignal(int)  # 定义一个信号

    def __init__(self, parent=None):

        super(WorkThread, self).__init__(parent)

    def run(self):

        for i in range(1, 101):

            time.sleep(0.1)  # 模拟耗时操作

            self.change_value_signal.emit(i)  # 发送信号

class MyApp(QMainWindow):

    def __init__(self, parent=None):

        super(MyApp, self).__init__(parent)

        widgets = QWidget()

        grid_layout = QGridLayout()

        self.btn_start = QPushButton('开始')

        self.btn_start.clicked.connect(self.start_work_thread)

        self.label_percent = QLabel('0/100')

        grid_layout.addWidget(self.btn_start)

        grid_layout.addWidget(self.label_percent)

        widgets.setLayout(grid_layout)

        self.setCentralWidget(widgets)

        self.thread = WorkThread(self)

        self.thread.change_value_signal.connect(self.update_ui)

    def start_work_thread(self):

        self.thread.start()

    def update_ui(self, val):

        self.label_percent.setText('{}/100'.format(val))

if __name__ == '__main__':

    import sys

    app = QApplication(sys.argv)

    myapp = MyApp()

    myapp.show()

    sys.exit(app.exec_())

在这个例子中,我们创建了一个WorkThread线程类,并在其中定义一个change_value_signal信号。然后在run()方法中,线程每隔0.1秒向change_value_signal信号发射当前进度值。

在MyApp类中,我们关联了btn_start按钮的clicked()事件与start_work_thread()方法。在start_work_thread()方法中,我们创建了一个WorkThread线程实例,并调用其start()方法来启动线程。

我们还定义了一个update_ui()方法,该方法将用于接收WorkThread线程发射的change_value_signal信号,并根据接收到的信号更新UI界面。

在MyApp的构造函数中,我们将change_value_signal信号连接到update_ui()方法中,这表明change_value_signal信号发射时将调用update_ui()方法来更新UI。

在这个例子中,我们使用QLabel来显示当前进度。当我们单击btn_start按钮时,线程开始运行,并且QLabel的值每隔0.1秒更新一次,直到达到进度值100。

总之,对于需要更新UI的多线程程序,我们可以使用PyQtSignal来解决这个问题。这个机制很有用,可以使得我们能够实现线程间的异步通信,从而更好地管理线程并更新UI。