插件窝 干货文章 PyQt5多线程:如何优雅地暂停和恢复线程而非强制终止?

PyQt5多线程:如何优雅地暂停和恢复线程而非强制终止?

self 线程 resume pause 170    来源:    2025-03-15

在PyQt5中,使用多线程时,通常我们会使用QThread来创建和管理线程。为了优雅地暂停和恢复线程,而不是强制终止线程,我们可以使用一些同步机制,比如QMutexQWaitCondition等。

下面是一个简单的示例,展示了如何在PyQt5中实现线程的暂停和恢复:

import sys
import time
from PyQt5.QtCore import QThread, QMutex, QWaitCondition, pyqtSignal
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton, QLabel

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

    def __init__(self):
        super().__init__()
        self.mutex = QMutex()
        self.condition = QWaitCondition()
        self.paused = False

    def run(self):
        count = 0
        while True:
            self.mutex.lock()
            if self.paused:
                self.condition.wait(self.mutex)
            self.mutex.unlock()

            self.update_signal.emit(f"Count: {count}")
            count += 1
            time.sleep(1)

    def pause(self):
        self.mutex.lock()
        self.paused = True
        self.mutex.unlock()

    def resume(self):
        self.mutex.lock()
        self.paused = False
        self.condition.wakeAll()
        self.mutex.unlock()

class MainWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle('PyQt5 Thread Pause/Resume Example')
        self.setGeometry(100, 100, 300, 200)

        layout = QVBoxLayout()

        self.label = QLabel('Count: 0', self)
        layout.addWidget(self.label)

        self.pause_button = QPushButton('Pause', self)
        self.pause_button.clicked.connect(self.pause_thread)
        layout.addWidget(self.pause_button)

        self.resume_button = QPushButton('Resume', self)
        self.resume_button.clicked.connect(self.resume_thread)
        layout.addWidget(self.resume_button)

        self.setLayout(layout)

        self.worker = Worker()
        self.worker.update_signal.connect(self.update_label)
        self.worker.start()

    def update_label(self, text):
        self.label.setText(text)

    def pause_thread(self):
        self.worker.pause()

    def resume_thread(self):
        self.worker.resume()

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

代码说明:

  1. Worker类:继承自QThread,负责执行后台任务。run方法中有一个无限循环,每隔1秒更新一次计数。pauseresume方法用于暂停和恢复线程。

  2. MainWindow类:主窗口类,包含一个标签和两个按钮(暂停和恢复)。点击按钮会调用Worker类的pauseresume方法。

  3. QMutex和QWaitConditionQMutex用于保护共享资源,QWaitCondition用于线程间的同步。当线程被暂停时,QWaitCondition会使线程进入等待状态,直到resume方法被调用并唤醒线程。

运行效果:

  • 点击“Pause”按钮,线程会暂停计数。
  • 点击“Resume”按钮,线程会恢复计数。

注意事项:

  • 这种方法适用于需要频繁暂停和恢复线程的场景。
  • 如果线程中有复杂的任务,可能需要更复杂的同步机制来确保线程安全。

通过这种方式,你可以优雅地控制线程的暂停和恢复,而不是强制终止线程。