python pyside2 QThread线程 作者:马育民 • 2025-09-15 15:56 • 阅读:10003 # 介绍 在 PySide2 中,线程处理是避免 UI 卡顿的关键技术,尤其是在执行耗时操作时。以下是 PySide2 线程使用的详细指南和示例: ### 应用场景 - [进度条](https://www.malaoshi.top/show_1GW1rlopNlG4.html "进度条") # 例子 ``` import sys import time from PySide2.QtWidgets import (QApplication, QWidget, QVBoxLayout, QPushButton, QTextEdit, QProgressBar) from PySide2.QtCore import QThread, Signal, Qt # 1. 自定义线程类(继承QThread) class WorkerThread(QThread): # 定义信号:用于向主线程发送数据 update_signal = Signal(str) # 发送文本更新 progress_signal = Signal(int) # 发送进度更新 finished_signal = Signal() # 发送任务完成信号 def __init__(self, task_duration=10): super().__init__() self.task_duration = task_duration # 任务持续时间(秒) self.is_running = True # 控制线程运行的标志 def run(self): """线程执行的任务(耗时操作放在这里)""" try: for i in range(101): # 检查是否需要停止 if not self.is_running: self.update_signal.emit("任务被取消") return # 发送进度更新 self.progress_signal.emit(i) # 发送文本更新 if i % 10 == 0 and i > 0: self.update_signal.emit(f"任务进度:{i}%") # 模拟耗时操作 time.sleep(self.task_duration / 100) # 任务完成 self.update_signal.emit("任务完成!") self.finished_signal.emit() except Exception as e: self.update_signal.emit(f"发生错误:{str(e)}") def stop(self): """停止线程""" self.is_running = False self.wait() # 等待线程结束 # 2. 主窗口类 class ThreadDemoWindow(QWidget): def __init__(self): super().__init__() self.thread = None # 线程实例 self.initUI() def initUI(self): # 创建布局 layout = QVBoxLayout() layout.setSpacing(15) # 文本显示区域 self.text_edit = QTextEdit() self.text_edit.setReadOnly(True) layout.addWidget(self.text_edit) # 进度条 self.progress_bar = QProgressBar() self.progress_bar.setRange(0, 100) layout.addWidget(self.progress_bar) # 控制按钮 self.start_btn = QPushButton("开始任务") self.start_btn.clicked.connect(self.start_thread) self.stop_btn = QPushButton("停止任务") self.stop_btn.clicked.connect(self.stop_thread) self.stop_btn.setEnabled(False) # 初始禁用 # 添加按钮到布局 btn_layout = QVBoxLayout() btn_layout.addWidget(self.start_btn) btn_layout.addWidget(self.stop_btn) layout.addLayout(btn_layout) self.setLayout(layout) # 窗口设置 self.setWindowTitle("PySide2 线程示例") self.setGeometry(300, 300, 500, 300) self.show() def start_thread(self): """启动线程""" # 确保之前的线程已停止 if self.thread and self.thread.isRunning(): self.thread.stop() # 创建并配置线程 self.thread = WorkerThread(task_duration=5) # 任务持续5秒 # 连接信号与槽 self.thread.update_signal.connect(self.update_text) self.thread.progress_signal.connect(self.update_progress) self.thread.finished_signal.connect(self.on_task_finished) # 启动线程 self.thread.start() # 更新UI状态 self.start_btn.setEnabled(False) self.stop_btn.setEnabled(True) self.text_edit.append("任务开始...") def stop_thread(self): """停止线程""" if self.thread and self.thread.isRunning(): self.thread.stop() self.update_text("任务已停止") self.on_task_finished() def update_text(self, message): """更新文本显示(在主线程中执行)""" self.text_edit.append(message) def update_progress(self, value): """更新进度条(在主线程中执行)""" self.progress_bar.setValue(value) def on_task_finished(self): """任务完成后更新UI状态""" self.start_btn.setEnabled(True) self.stop_btn.setEnabled(False) def closeEvent(self, event): """窗口关闭时确保线程已停止""" if self.thread and self.thread.isRunning(): self.thread.stop() event.accept() if __name__ == '__main__': app = QApplication(sys.argv) window = ThreadDemoWindow() sys.exit(app.exec_()) ``` ### 线程使用核心要点 1. **线程创建方式** - 继承 `QThread` 并重写 `run()` 方法(示例中使用的方式) - 使用 `QRunnable` 和 `QThreadPool`(适合短期任务) 2. **线程与UI通信** - 必须通过 **信号(Signal)** 和 **槽(Slot)** 进行通信 - 绝对不要在子线程中直接操作UI控件(会导致崩溃) 3. **线程生命周期管理** - 使用标志位(如 `is_running`)控制线程安全退出 - 线程结束时调用 `wait()` 确保资源正确释放 - 窗口关闭前停止所有线程 4. **线程安全注意事项** - 共享数据需要加锁(使用 `QMutex`) - 避免在子线程中创建或销毁UI对象 - 长时间运行的线程应提供停止机制 ### 常见应用场景 - 文件IO操作(读取大文件、批量处理文件) - 网络请求(API调用、数据下载) - 耗时计算(数据分析、图像处理) - 定时任务(周期性数据更新) 使用线程可以确保UI在执行耗时操作时保持响应,提升用户体验。示例中展示的线程通信模式是PySide2中最常用和推荐的方式。 原文出处:http://www.malaoshi.top/show_1GW1rlplwTIE.html