当前位置: 首页 > ai >正文

PyQt6基础_QThread

目录

前置

代码: 

运行

正常运行

QThread运行报错

 视频


前置

1 PySide6.QtCore.QThread - Qt for Python QThread官方文档

2 长时间任务可以放到QThread中执行,避免占用主线程导致界面卡顿无法操作

代码: 

import traceback,sys
from datetime import datetime
from time import sleep
from PyQt6.QtCore import (
Qt,
QSize,
QThread,
QTime,
QObject,
pyqtSignal,
pyqtSlot
)
from PyQt6.QtWidgets import (
QApplication,
QMainWindow,
QLabel,
QPushButton,
QVBoxLayout,
QWidget,
QMessageBox
)class Worker_000(QObject):signal_finished = pyqtSignal(str) # 任务结束信号signal_error = pyqtSignal(tuple) # 任务报错信号signal_result = pyqtSignal(str) # 任务返回的结果@pyqtSlot(object)def do_work(self,task_data:dict):thread_name = task_data['thread_name']res_str = '执行结束了。'try:# work code startfor i in range(20):if i==10:raise ValueError('测试报错功能')self.signal_result.emit(f"线程返回 第{i}次,当前时间为 {QTime.currentTime().toString('hh:mm:ss')} ")sleep(1)pass# work code endpassexcept:traceback.print_exc()exctype,value = sys.exc_info()[:2]self.signal_error.emit((thread_name,exctype,value,traceback.format_exc()))passelse:self.signal_result.emit(res_str)finally:self.signal_finished.emit(thread_name)passpassclass MainWindow(QMainWindow):signal_worker = pyqtSignal(object)def __init__(self):super().__init__()self.setWindowTitle('QThread')self.setMinimumSize(QSize(600,400))self.label_worker = QLabel()self.label_main = QLabel()self.btn = QPushButton('启动QThread',clicked=self.btn_clicked)self.btn00 = QPushButton('主界面',clicked=self.btn00_clicked)layout = QVBoxLayout()layout.addWidget(self.label_worker)layout.addWidget(self.btn)layout.addWidget(self.btn00)layout.addWidget(self.label_main)widget = QWidget()widget.setLayout(layout)self.setCentralWidget(widget)self.open_init()passdef open_init(self):self.thread = Noneself.worker = Noneself.waitting_close = Falsepassdef btn_clicked(self):self.btn.setDisabled(True)self.worker = Worker_000()self.thread = QThread()self.thread.finished.connect(self.thread_finished)self.worker.signal_finished.connect(self.worker_signal_finished_emit)self.worker.signal_error.connect(self.worker_signal_error_emit)self.worker.signal_result.connect(self.worker_signal_results_emit)# 主线程与子线程之间的交互必须通过信号与槽进行,不要在主线程中通过 self.worker.do_woker()self.signal_worker.connect(self.worker.do_work)# 由于是通过 moveToThread 启动 QThread.run() ,QThread不会自动发起finished信号,需要手动 quit或exit后才会发送finishedself.worker.moveToThread(self.thread)self.thread.start()task_data = {'thread_name':'worker_000'}self.signal_worker.emit(task_data)print('线程开始了。')passdef btn00_clicked(self):now_str = datetime.now().strftime('%Y-%m-%d %H:%M:%S')if self.thread:if self.thread.isRunning():res_str = '线程正在执行中...'else:res_str = '悠闲,哈哈哈'else:res_str = '无聊中。呵呵呵'self.label_main.setText(f"{now_str} {res_str}")passdef thread_finished(self):print('线程finished')self.btn.setDisabled(False)if self.waitting_close:self.close()passpassdef worker_signal_finished_emit(self,res:str):print(f'{res} 线程任务结束。')self.thread.quit()passdef worker_signal_error_emit(self,res:tuple):# (thread_name,type,value,traceback)pre_str = f"线程 {res[0]} 报错啦。报错信息 {res[-1]}"print(pre_str)QMessageBox.information(self,'提示',pre_str,QMessageBox.StandardButton.Ok)passdef worker_signal_results_emit(self,res:str):self.label_worker.setText(res)passdef closeEvent(self, a0):answer = QMessageBox.question(self,'确认退出?','退出将中断操作,确定要退出么?',QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No)if answer == QMessageBox.StandardButton.Yes:if self.thread:if self.thread.isRunning():self.waitting_close = Trueself.thread.quit()a0.ignore()QMessageBox.information(self,'提示','正在关闭线程,请稍等',QMessageBox.StandardButton.Ok)passelse:a0.accept()else:a0.accept()else:a0.ignore()passif __name__ == '__main__':app = QApplication([])mw = MainWindow()mw.show()app.exec()pass

1 主线程与QThread之间的交互必须通过信号与槽进行

2 Work_000类是要子线程执行的任务,使用 moveToThread 方法调用QThread。注意:使用moveToThread方法调用QThread,QThread不会自主发射finished信号,需要手动quit或exit才会发射finished信号。所以在主线程接收到 Work_000 signal_finished表示任务完成的信号时,手动将QThread quit或exit

3 存在QThread的程序需要考虑一种情况,就是在QThread还在执行中时,关闭主界面(主线程)的情况。所以,定义了一个 waitting_close 布尔变量,如果发生QThread还在执行,但发起关闭主界面的请求时,将 waitting_close设置为True。在 QThread 发射finished信号后,检查 watting_close 是否为True,如果为True,就将主界面关闭。

运行

正常运行

控制台打印

QThread启动后,“启动QThread"按钮不可用。QThread执行过程中,”主界面“按钮可以正常使用。

QThread执行结束后,QThread发射finished信号,“启动QThread"按钮恢复可用状态。

QThread运行报错

 

控制台打印

 视频

PyQt6基础_QThread_哔哩哔哩_bilibili 

http://www.xdnf.cn/news/2724.html

相关文章:

  • 亚马逊如何分析竞品
  • 网工笔记-网络层
  • 软件工程(一):黑盒测试与白盒测试
  • 【浙江大学DeepSeek公开课】人类经验与AI算法的镜像之旅
  • 考研系列-计算机组成原理第七章、输入/输出系统
  • 解锁健康密码:养生的多维智慧
  • 【手册】Linux服务器应急排查实战指南
  • 《Learning Langchain》阅读笔记11-RAG(7)索引优化:RAPTOR方法和ColBERT方法
  • C++:BST、AVL、红黑树
  • 惠普P1108打印机信息
  • gre over ipsec (神州数码)
  • 巧记英语四级单词 Unit6-中【晓艳老师版】
  • SpringBoot启动后自动执行方法的各种方式-笔记
  • 【MCP】第三篇:Cline工具链路追踪——解码“协议引擎“的神经传导奥秘
  • Pytest-mark使用详解(跳过、标记、参数 化)
  • 夜莺 v8.0.0-beta.10 部署
  • 新能源汽车声纹监测技术的发展趋势是什么?
  • 机器学习:【抛掷硬币的贝叶斯后验概率】
  • 【MySQL】-- 增删改查操作(1)
  • AI辅助编程-cursor开发煤矿持证上岗管理程序需求与设计篇
  • python tk.text不可编辑
  • 高效运维,智慧监测:COMEM光纤温度测量系统在电力行业中的应用
  • 云服务器被黑客攻击应急响应与加固指南(上)
  • Shiro学习(七):总结Shiro 与Redis 整合过程中的2个问题及解决方案
  • 网络安全入门综述
  • 深入了解指针(6)
  • day004-习题
  • Python实例题:Pvthon实现键值数据库
  • 入门版 鸿蒙 组件导航 (Navigation)
  • 游戏打击感实现