前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >PySide6 GUI 编程(46): 基于QThread构造常驻后台的线程

PySide6 GUI 编程(46): 基于QThread构造常驻后台的线程

原创
作者头像
bowenerchen
发布2024-09-17 09:00:37
2100
发布2024-09-17 09:00:37
举报
文章被收录于专栏:编码视界

QRunnable与QThread的使用区别

在 PySide6 中,QRunnableQThread 都可以用来在后台执行任务,但它们的使用场景和设计目的有所不同。

使用 QRunnable

QRunnable 是一个轻量级的便利类,用于封装一个可以在线程池中执行的任务。它通常用于以下情况:

  1. 任务是短暂的QRunnable 适用于执行一些快速的、独立的任务。因为它们是在线程池中运行的,所以可以有效地重用线程,避免了频繁创建和销毁线程的开销。
  2. 大量的、小型的任务:如果你的应用程序需要处理大量的小任务,使用 QRunnable 可以避免操作系统线程数量的限制,因为线程池会管理这些线程的生命周期,并根据需要重用它们。
  3. 不需要详细控制线程行为QRunnable 提供的控制相对较少,主要关注任务的执行。如果你不需要管理线程的暂停、恢复或其他复杂的线程管理操作,QRunnable 是一个好选择。

使用 QThread

QThread 是 Qt 的线程类,它提供了完整的线程功能,包括线程的生命周期管理、信号槽机制等。它适用于以下情况:

  1. 长时间运行的任务:如果你有一个需要长时间运行的后台任务,比如持续监控或处理数据流,使用 QThread 可以给你更多的控制和灵活性。
  2. 需要复杂交互的线程QThread 支持 Qt 的信号和槽机制,这使得线程之间的通信变得简单。如果你的线程需要与其他线程或主线程频繁交互,QThread 提供的功能会更加合适。
  3. 需要精细控制线程的行为:如果你需要对线程进行详细的控制,比如调整优先级、暂停、恢复或其他特定的线程管理操作,QThread 提供了这些能力。

总结

  • 选择 QRunnable:当你需要处理许多短暂的、独立的任务,并且希望通过线程池来优化性能和资源使用。
  • 选择 QThread:当你的任务需要长时间运行,或者需要复杂的线程管理和线程间通信。

使用QThread 构造常驻后台的线程

示例代码

代码语言:python
代码运行次数:0
复制
from __future__ import annotations
import sys
from datetime import datetime

from PySide6.QtCore import QThread, Signal, Slot
from PySide6.QtWidgets import QApplication, QLabel, QMainWindow, QPushButton, QVBoxLayout, QWidget

class CounterThread(QThread):
    update_count = Signal(str)  # 发送带时间戳的计数信息

    def __init__(self):
        super().__init__()
        self.running = False
        self.paused = False

    def run(self):
        count = 0
        self.running = True
        while self.running:
            if not self.paused:
                timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
                message = f"{timestamp} - Count: {count}"
                self.update_count.emit(message)
                count += 1
                self.sleep(1)

    def pause_or_resume(self):
        self.paused = not self.paused

    def stop(self):
        self.running = False
        self.paused = False


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.counter_thread = CounterThread()
        self.start_button = QPushButton("Start", self)
        self.toggle_pause_button = QPushButton("Pause", self)
        self.stop_button = QPushButton("Stop", self)
        self.count_label = QLabel("Counter not started", self)
        self.init_ui()

    def init_ui(self):
        self.setWindowTitle("Thread Control Example")

        self.start_button.clicked.connect(self.start_thread)
        self.toggle_pause_button.clicked.connect(self.toggle_pause)
        self.stop_button.clicked.connect(self.stop_thread)

        self.toggle_pause_button.setEnabled(False)  # 初始时Pause按钮不可用

        layout = QVBoxLayout()
        layout.addWidget(self.start_button)
        layout.addWidget(self.toggle_pause_button)
        layout.addWidget(self.stop_button)
        layout.addWidget(self.count_label)

        container = QWidget()
        container.setLayout(layout)
        self.setCentralWidget(container)

        self.counter_thread.update_count.connect(self.handle_count_update)

    @Slot(str)
    def handle_count_update(self, message):
        self.count_label.setText(message)

    def start_thread(self):
        if not self.counter_thread.isRunning():
            self.counter_thread.start()
            self.toggle_pause_button.setText("Pause")
            self.toggle_pause_button.setEnabled(True)  # 启动后Pause按钮可用

    def toggle_pause(self):
        self.counter_thread.pause_or_resume()
        if self.counter_thread.paused:
            self.toggle_pause_button.setText("Resume")
        else:
            self.toggle_pause_button.setText("Pause")

    def stop_thread(self):
        self.counter_thread.stop()
        self.counter_thread.wait()  # 等待线程安全结束
        self.count_label.setText("Counter stopped")
        self.toggle_pause_button.setEnabled(False)  # 停止后Pause按钮不可用


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

运行效果

控制常驻后台的 QThread 线程
控制常驻后台的 QThread 线程

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • QRunnable与QThread的使用区别
    • 使用 QRunnable
      • 使用 QThread
        • 总结
        • 使用QThread 构造常驻后台的线程
          • 示例代码
            • 运行效果
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档