问题:点击<开始>按钮后加载模型计算,pyqt界面卡住等待计算结束。目的是添加进度条,优化用户等待。一开始以为添加进度条加上时钟就行,调试后发现把计算部分写在主界面类里,计算和进度条无法一起进行。
解决:需要把计算部分分离出去另起一个线程。
以我程序所写的线程类为参考如下
from PyQt5.QtCore import *
class MyCal(QThread):
#自定义一个信号名
cal_signal = pyqtSignal(np.ndarray, np.ndarray) #定义信号返回的数值类型
#构造函数
def __init__(self, model, img, parent=None): #model为传入的模型,img为传入的要处理的图片
super(MyCal, self).__init__(parent)
self.work = True
self.model = model
self.cam_image = img
#析构函数
def __del__(self):
self.work = False
self.wait()
#该线程主程序
def run(self):
mask, overley = self.model.predict(self.cam_image)
self.cal_signal.emit(mask, overley) #发射信号,传参数
在主线程界面中调用上面的线程 并 设置进度条时钟
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent=parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
#此处省略一系列初始化操作
######################
self.pbar = self.ui.progressBar
self.timer = QBasicTimer() #初始化一个时钟
self.step = 0 #进度条的值
self.ui.btn_run.clicked.connect(self.btn_click) #连接槽函数
def btn_click(self):
if self.cam_image is None:
return
self.ui.btn_run.setEnabled(False)
self.timer.start(100, self) #启动QBasicTimer,每100ms调用一次事件回调函数
self.cal = MyCal(self.model, self.cam_image) #点击按钮后新建计算的线程
self.cal.cal_signal.connect(self.cal_callback) #连接计算线程的信号
self.cal.start() #开始运行线程
def cal_callback(self, mask, overley): #接收到计算线程信号后的回掉函数
#省略 使用接收到线程返回的参数
##########################
def timerEvent(self, *args, **kwargs): #QBasicTimer的事件回调函数
# 把进度条每次充值的值赋给进度条
self.pbar.setValue(self.step)
if self.step >= 100:
# 停止进度条
self.timer.stop()
self.step = 0
return
#把进度条卡在99,等处理好了再到100
if self.step < 99:
self.step += 1