前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >有坑 | PyQT多线程无法刷新,导致界面卡死

有坑 | PyQT多线程无法刷新,导致界面卡死

作者头像
OpenCV学堂
发布2022-08-29 11:53:37
3.8K0
发布2022-08-29 11:53:37
举报
文章被收录于专栏:贾志刚-OpenCV学堂

点击上方蓝字关注我们

微信公众号:OpenCV学堂 关注获取更多计算机视觉与深度学习知识

问题背景与描述

我这两天一直想把YOLOv5上加个训练的界面,把控制台的输出重定向到一个PyQT5写的界面上,然后我很顺序的写好了一个简单的测试,发现可以重定向了,一直实时获取输出了。代码如下:

然后我就写了个界面,让控制台显示到界面的texteditor中,我知道训练是一个长耗时的操作过程,所以我单独开启了一个QThread线程来完成,然后在线程中发送获取的控制台输出文本给界面主线程,完成界面刷新。以前我用QT C++就是这样干的,所以这个肯定可以。于是写一个线程类,大致如下:

代码语言:javascript
复制
class TrainTask(QThread):
    textWritten = QtCore.pyqtSignal(str)


    def __init__(self, command_txt):
        QThread.__init__(self)
        self.cmd_txt = command_txt


    def __del__(self):
        self.wait()


    def run(self):
        self.textWritten.emit("test refresh ui")
        for i in range(1000):
            self.textWritten.emit("test refresh ui")
            self.msleep(1)

然后在界面类中通过一个按钮点击开启它, 然后它就会开始发送数据到界面类指定方法outputWritten中。绑定按钮响应事件:

代码语言:javascript
复制
self.start_training_btn.clicked.connect(self.start_traning_action)

点击按钮执行:

代码语言:javascript
复制
my_train = TrainTask(cmd_txt + params)my_train.textWritten.connect(self.outputWritten)my_train.start()

我以为上述代码是天衣无缝,这样就大功告成了,实际上是界面直接卡死了,还有天理吗?多线程居然阻塞返回之后才刷新?!!!

问题现象与解决

把线程中的for训练语句去掉,单独发消息跟界面类,发现可以成功。一旦放开,在run方法中使用for或while之后,就会一直等到结束才返回刷新界面,说明开启的线程没有异步,还是阻塞执行,导致界面卡死

01

尝试一:

网上一通搜索,有人告诉我说必须先定义一个work类,然后把work类移到QThread线程实例中,测试了是个锤子,没用

02

尝试二:

说在线程run方法中导致CPU无法轮询,一定就不是很合理的解释,必须要用线程的sleep方法才行,测试了还是个锤子,没用

03

解决方法:

之前的卡死界面线程的代码没有错的,错就错在调用方法,错误的调用方式

代码语言:javascript
复制
my_train = TrainTask(cmd_txt + params)
my_train.textWritten.connect(self.outputWritten)
my_train.start()

重点来了,正确的调用方式如下:

代码语言:javascript
复制
self.my_train = TrainTask(cmd_txt + params)self.my_train.textWritten.connect(self.outputWritten)self.my_train.finished_signal.connect(self.do_finish_action)self.my_train.finished.connect(self.my_train.deleteLater)self.my_train.start()self.start_training_btn.setEnabled(False)self.stop_training_btn.setEnabled(True)

总结一句话:

一定要把线程变量声明为界面类的成员变量,而不是方法中临时变量,是临时变量必然卡死界面,无法刷新,这个是折腾一天得到的教训!网上搜不到!!!

解决了这个问题之后,我很快写好了一个YOLOv5从界面直接开启训练的演示界面,如下图所示,准备好数据,点几下按钮就可以训练YOLOv5,生成模型了!

后来我又添加了一个高级参数设置,发现更好用了!

从此训练YOLOv5, 只要标注好数据,剩下点点鼠标就好了!

扫码查看OpenCV+OpenVIO+Pytorch系统化学习路线图

 推荐阅读 

CV全栈开发者说 - 从传统算法到深度学习怎么修炼

2022入坑深度学习,我选择Pytorch框架!

Pytorch轻松实现经典视觉任务

教程推荐 | Pytorch框架CV开发-从入门到实战

OpenCV4 C++学习 必备基础语法知识三

OpenCV4 C++学习 必备基础语法知识二

OpenCV4.5.4 人脸检测+五点landmark新功能测试

OpenCV4.5.4人脸识别详解与代码演示

OpenCV二值图象分析之Blob分析找圆

OpenCV4.5.x DNN + YOLOv5 C++推理

OpenCV4.5.4 直接支持YOLOv5 6.1版本模型推理

OpenVINO2021.4+YOLOX目标检测模型部署测试

比YOLOv5还厉害的YOLOX来了,官方支持OpenVINO推理

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-08-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 OpenCV学堂 微信公众号,前往查看

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

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
人脸识别
腾讯云神图·人脸识别(Face Recognition)基于腾讯优图强大的面部分析技术,提供包括人脸检测与分析、比对、搜索、验证、五官定位、活体检测等多种功能,为开发者和企业提供高性能高可用的人脸识别服务。 可应用于在线娱乐、在线身份认证等多种应用场景,充分满足各行业客户的人脸属性识别及用户身份确认等需求。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档