I have a very long list to deal with, so I use multiprocessing to speed up the process. Now I want to show the progress in a PyQt5.QtWidgets.QProgressBar. This is the code:
import sys
from PyQt5.QtWidgets import *
import multiprocessing as mp
import threading
targets = list(range(0, 100))
def process(i):
print("target:", i)
# do something, for example:
for c in range(1000):
for r in range(1000):
c = c * r + 4
class MainWin(QWidget):
def __init__(self):
super(MainWin, self).__init__()
self.setupUi()
def setupUi(self):
self.setFixedSize(500, 90)
self.layout = QGridLayout()
self.main_widget = QWidget(self)
self.progressBar = QProgressBar()
self.progressBar.setValue(0)
self.btn = QPushButton('start')
self.layout.addWidget(self.progressBar, 0, 0, 1, 1)
self.layout.addWidget(self.btn, 1, 0, 1, 1)
self.setLayout(self.layout)
self.btn.clicked.connect(self.run)
def display(self, args):
self.progressBar.setValue(self.progressBar.value() + 1)
print("process bar:", self.progressBar.value())
# QApplication.processEvents() # I've tried this function and it has no effect
def run(self):
def func(results):
pool = mp.Pool()
for t in targets:
pool.apply_async(process, (t,), callback=self.display)
results.append(t)
pool.close()
pool.join()
results = []
t = threading.Thread(target=func, args=(results,))
t.start()
# everything is fine without t.join(), but the progress bar always gets stuck when t.join() is called
# t.join()
# pass # do something with the results
if __name__ == '__main__':
app = QApplication(sys.argv)
main_win = MainWin()
main_win.show()
sys.exit(app.exec_())
Everything is fine without the "t.join()" called. But to gain a complete "results", I have to wait for the end of the thread, in which condition the processBar always gets stuck at around 40%.
How to fix this?