PyQT多线程正确的调用方式

描述

 

问题背景与描述

我这两天一直想把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,生成模型了!

pyqt

pyqt

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

pyqt

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

      审核编辑:彭静
打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分