PyQt QProgressBar no funciona cuando lo uso con Selenuim

Construí una GUI de PyQt5 para hacer algunas pruebas de Selenium. Todo funciona como se espera, excepto la barra de progreso de PyQt.

En el primer ejemplo a continuación, donde uso el navegador Selenium, la barra de progreso simplemente salta al 100%, al final, cuando se cierra el navegador. Pero, el selenium funciona como se espera.

def test(self): self.completed = 0 browser = webdriver.Firefox() links = ['http://www.somesite.com/', 'http://www.somesite.com/page2', 'http://www.somesite.com/page3'] for link in links: browser.get(link) self.completed += 100 / len(links) time.sleep(2) print(link) self.progressBar.setValue(self.completed) browser.close() 

Pero, en esta versión a continuación, con el navegador Selenium comentado, la barra de progreso funciona como se esperaba.

 def test(self): self.completed = 0 #browser = webdriver.Firefox() links = ['http://www.somesite.com/', 'http://www.somesite.com/page2', 'http://www.somesite.com/page3'] for link in links: #browser.get(link) self.completed += 100 / len(links) time.sleep(2) print(link) self.progressBar.setValue(self.completed) #browser.close() 

Las tareas de locking no son amigables con el bucle de eventos donde se ejecuta la GUI, ya que impiden que se ejecuten las tareas normales que realiza la GUI, como la verificación de tickets, el redibujado, etc.

La solución en estos casos es usar un hilo para ejecutar la tarea de locking y usar las señales para enviar la información.

 import sys from PyQt5 import QtCore, QtWidgets from selenium import webdriver class SeleniumWorker(QtCore.QObject): progressChanged = QtCore.pyqtSignal(int) def doWork(self): progress = 0 browser = webdriver.Firefox() links = ['http://www.somesite.com/', 'http://www.somesite.com/page2', 'http://www.somesite.com/page3'] for link in links: browser.get(link) progress += 100 / len(links) self.progressChanged.emit(progress) browser.close() class Widget(QtWidgets.QWidget): def __init__(self, *args, **kwargs): QtWidgets.QWidget.__init__(self, *args, **kwargs) lay = QtWidgets.QHBoxLayout(self) progressBar = QtWidgets.QProgressBar() progressBar.setRange(0, 100) button = QtWidgets.QPushButton("Start") lay.addWidget(progressBar) lay.addWidget(button) self.thread = QtCore.QThread() self.worker = SeleniumWorker() self.worker.moveToThread(self.thread) self.thread.started.connect(self.worker.doWork) button.clicked.connect(self.thread.start) self.worker.progressChanged.connect(progressBar.setValue, QtCore.Qt.QueuedConnection) if __name__ == '__main__': app = QtWidgets.QApplication(sys.argv) w = Widget() w.show() sys.exit(app.exec_())