问题:使用pyqt5来显示一个函数的进度,但是这个函数被封装了很多次,如何显示进度?
解决方案:
子函数功能:建立一个WorkerThread,里面使用pyqtSignal来向主窗口发送信号,将WorkerThread类里实例化的pyqtSignal,进行层层传递,一直传递给实际想监控的功能里,通过emit()函数把信号发送出去。
主函数:实例化WorkerThread,并绑定更新进度条事件,一旦接收到信号,执行该更新进度条事件
import sys
import time
from PyQt5.QtWidgets import QApplication, QWidget, QProgressBar, QPushButton, QVBoxLayout
from PyQt5.QtCore import QBasicTimer, QThread, pyqtSignal
class InnerClass:
def execute(self, progress_update):
# 模拟复杂的耗时操作
for i in range(101):
time.sleep(0.1) # 模拟工作
# 发射信号通知进度
progress_update.emit(i)
class MiddleClass:
def execute(self, progress_update):
inner_instance = InnerClass()
inner_instance.execute(progress_update)
class WorkerThread(QThread):
progress_update = pyqtSignal(int)
def __init__(self):
super().__init__()
def run(self):
middle_instance = MiddleClass()
middle_instance.execute(self.progress_update)
class Example(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.pbar = QProgressBar(self)
self.pbar.setGeometry(30, 40, 200, 25)
self.btn = QPushButton('开始', self)
self.btn.clicked.connect(self.toggleAction)
layout = QVBoxLayout()
layout.addWidget(self.pbar)
layout.addWidget(self.btn)
self.setLayout(layout)
self.worker_thread = WorkerThread()
self.worker_thread.progress_update.connect(self.updateProgressBar)
self.timer = QBasicTimer()
self.step = 0
self.setGeometry(300, 300, 280, 170)
self.setWindowTitle('进度条')
self.show()
def timerEvent(self, e):
if self.step >= 100:
self.step = 0
self.pbar.setValue(self.step)
self.timer.stop()
self.btn.setText('开始')
return
self.step += 1
self.pbar.setValue(self.step)
def toggleAction(self):
if self.timer.isActive():
self.timer.stop()
self.btn.setText('开始')
else:
self.timer.start(100, self)
self.btn.setText('停止')
# 启动工作线程以执行耗时函数
self.worker_thread.start()
def updateProgressBar(self, value):
# 根据工作线程发出的值更新进度条
self.pbar.setValue(value)
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())