📜  如何在 PyQt5 中使用线程?(1)

📅  最后修改于: 2023-12-03 15:38:23.181000             🧑  作者: Mango

如何在 PyQt5 中使用线程?

在 PyQt5 中使用线程可以有效避免在 GUI 主线程中进行耗时操作导致 UI 无法响应的情况。本文将介绍使用 PyQt5 中的 QThread 类来实现线程操作。

1. 创建一个线程类

PyQt5 中的 QThread 类是一个抽象类,需要自定义一个继承自 QThread 的线程类。

class Worker(QThread):
    def __init__(self, parent=None):
        super().__init__(parent=parent)
    
    def run(self):
        # 在这里执行线程操作
        pass

在 run 方法中编写线程操作的代码。

2. 启动线程

在需要使用线程的地方,创建工作线程并启动。

worker = Worker()
worker.start()
3. 连接信号与槽

如果需要在线程中更新 UI,需要使用信号与槽机制。

class Worker(QThread):
    signal = pyqtSignal(str)

    def __init__(self, parent=None):
        super().__init__(parent=parent)
    
    def run(self):
        # 在这里执行线程操作,并发出信号
        self.signal.emit("Thread finished!")

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.label = QLabel()
        self.setCentralWidget(self.label)

        self.worker = Worker()
        self.worker.signal.connect(self.handle_signal)

        self.worker.start()

    def handle_signal(self, msg):
        self.label.setText(msg)

以上代码创建了一个新的 QThread 线程类,并在 MainWindow 类中创建了一个 QLabel,用于显示线程运行结果。在创建 Worker 对象后,连接 signal 信号与 handle_signal 槽函数。在 Worker 线程运行结束时调用 signal.emit() 方法发出信号,handle_signal 槽函数接收到信号后更新 QLabel 的显示文本。

4. 处理线程停止

在有些情况下,需要在使用线程的主程序结束时,停止线程运行。

class Worker(QThread):
    def __init__(self, parent=None):
        super().__init__(parent=parent)
        self.is_running = True
    
    def run(self):
        while self.is_running:
            pass

    def stop(self):
        self.is_running = False

在 Worker 中新增了一个实例变量 is_running,并在 run 方法中循环运行,直到 is_running 为 False。新增了一个 stop 方法,用于停止线程。

在主程序中,可以通过如下方式停止线程。

worker = Worker()
worker.start()
# ...
worker.stop()
总结

本文介绍了如何使用 PyQt5 中的 QThread 类创建线程,如何连接信号与槽机制,以及如何处理线程停止的问题。当我们需要在 GUI 中进行耗时操作时,使用线程可以使得 UI 正常响应,提高用户体验。