欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 新车 > PyQt6基础_QThread

PyQt6基础_QThread

2025/4/29 5:28:55 来源:https://blog.csdn.net/m0_37967652/article/details/147595973  浏览:    关键词: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 

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词