📜  如何在 pyqt5 中使用线程 - Python (1)

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

如何在 PyQt5 中使用线程

在 PyQt5 中使用线程可以将耗时的任务放到后台进行处理,从而避免长时间阻塞用户界面。下面介绍如何在 PyQt5 中使用线程。

1. 使用 QThread 类创建线程

在 PyQt5 中,我们通常使用 QThread 类创建线程。以下是一个简单的例子:

import sys
from PyQt5.QtCore import QThread

class Worker(QThread):
    def __init__(self, parent=None):
        super(Worker, self).__init__(parent)

    def run(self):
        # 耗时任务的代码
        pass

if __name__ == '__main__':
    app = QApplication(sys.argv)
    worker = Worker()
    worker.start()
    sys.exit(app.exec_())

在这个例子中,我们首先定义了一个继承自 QThread 的 Worker 类。我们将耗时任务的代码放在 run 方法中。在主程序中,我们创建了一个 Worker 对象并调用 start 方法来启动线程。

2. 使用信号/槽机制更新界面

在线程中进行耗时任务处理时,我们通常需要在界面中显示任务进度或结果。在 PyQt5 中,我们可以使用信号/槽机制实现线程和主界面的通信。以下是一个例子:

import sys
from PyQt5.QtCore import QThread, pyqtSignal

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

    def __init__(self, parent=None):
        super(Worker, self).__init__(parent)

    def run(self):
        result = '耗时任务的结果'
        self.result.emit(result)

class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)

        self.worker = Worker()
        self.worker.result.connect(self.update_result)
        self.worker.start()

    def update_result(self, result):
        # 用耗时任务的结果更新界面
        pass

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())

在这个例子中,我们定义了一个 result 信号,当任务完成后会发出该信号,并携带耗时任务的结果。在主界面中,我们将 result 信号连接到 update_result 槽函数,用耗时任务的结果更新界面。

3. 使用 QThreadPool 类创建线程池

如果要并发执行多个任务,则可以使用 QThreadPool 类创建线程池(线程池是一组可重复使用的线程)。以下是一个例子:

import sys
from PyQt5.QtCore import QThreadPool, QRunnable, QObject, pyqtSignal

class Worker(QObject):
    progress = pyqtSignal(int)

    def __init__(self, num):
        super(Worker, self).__init__()
        self.num = num

    def run(self):
        for i in range(100):
            self.progress.emit(i)
            # 耗时任务的代码
            pass

class Task(QRunnable):
    def __init__(self, worker):
        super(Task, self).__init__()
        self.worker = worker

    def run(self):
        self.worker.run()

if __name__ == '__main__':
    app = QApplication(sys.argv)

    threadpool = QThreadPool()
    for i in range(5):
        worker = Worker(i)
        task = Task(worker)
        worker.progress.connect(print)
        threadpool.start(task)

    sys.exit(app.exec_())

在这个例子中,我们首先定义了一个继承自 QObject 的 Worker 类,它用于执行耗时任务。我们通过 progress 信号来通知任务进度。然后我们定义了一个继承自 QRunnable 的 Task 类,它用于将 Worker 对象放入线程池中执行。在主程序中,我们创建了一个包含 5 个线程的线程池,并将 5 个 Worker 对象加入线程池中执行。

以上就是在 PyQt5 中使用线程的介绍。需要注意的是,多线程编程涉及到许多问题,例如线程安全、锁机制等,需要在实际使用中进行深入学习和实践。