1 year ago

#118610

test-img

NorthBig

QProgressBar stuck when QRunnable runs a loop function passed in

I have a calculating function that need to be sent to Qrunnable Worker as a parameter. Then, the calculating function runs with a 0-100 loop calculating in Worker's run function. The Problem is: the function is a separate loop function, I want to update a QProgressBar in the window. But, in the Worker, a progress signal can't send back to update progress bar value before the whole calculating function completed. This is really weird to me. I tried following code by updating the QProgressBar in the loop of the calculating function. But calculating is OK, the QProgressBar stuck....Why? How to handle this kind of problem?

import sys
import time
import traceback

from PyQt5.QtCore import QObject, QRunnable, QThreadPool, pyqtSignal, pyqtSlot
from PyQt5.QtWidgets import QApplication, QMainWindow,QProgressBar,QPushButton, QVBoxLayout, QWidget


class WorkerSignals(QObject):
    result_signal = pyqtSignal(str)


class Worker(QRunnable):
    def __init__(self, fn, *args, **kwargs):
        super().__init__()
        # Store constructor arguments (re-used for processing)
        self.fn = fn
        self.args = args
        self.kwargs = kwargs
        self.signals = WorkerSignals()

    @pyqtSlot()
    def run(self):
        result = self.fn()
        self.signals.result_signal.emit(result)


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.btn = QPushButton('Start Test')
        self.btn.clicked.connect(self.control_progressBar)
        self.progressBar = QProgressBar()
        self.progressBar.setValue(0)
        self.vlayout = QVBoxLayout()
        self.vlayout.addWidget(self.btn)
        self.vlayout.addWidget((self.progressBar))
        self.widget = QWidget()
        self.widget.setLayout(self.vlayout)
        self.setCentralWidget(self.widget)
        self.thread = QThreadPool()
        self.result = 0
        self.show()

    def control_progressBar(self):
        worker = Worker(self.calculate)
        worker.signals.result_signal.connect(self.output)
        self.thread.start(worker)

    def calculate(self):
        for i in range(100):
            self.result += i*i*i
            self.progressBar.setValue(i)
        return str(self.result)

    def output(self, result):
        print(result)

app = QApplication(sys.argv)
window = MainWindow()
app.exec_()

pyqt5

qprogressbar

qrunnable

0 Answers

Your Answer

Accepted video resources