备案 控制台
学习
实践
活动
专区
工具
TVP
写文章
专栏首页 贾志刚-OpenCV学堂 有坑 | PyQT多线程无法刷新,导致界面卡死
3 0

海报分享

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

点击上方蓝字关注我们

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

问题背景与描述

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

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

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中。绑定按钮响应事件:

self.start_training_btn.clicked.connect(self.start_traning_action)

点击按钮执行:

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

解决方法:

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

my_train = TrainTask(cmd_txt + params)
my_train.textWritten.connect(self.outputWritten)
my_train.start()

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

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版本模型推理