PyQt QProgressBar not working when I use it with S

2019-01-04 15:18发布

I built a PyQt5 GUI to do some Selenium testing. Everything works as expected, except for the PyQt progress bar.

In the first example below, where I use the Selenium browser, the progress bar just jumps to 100%, at the end, when the browser closes. But, the Selenium works as expected.

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()

But, in this version below, with the Selenium browser commented out, the progress bar works as expected.

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()

1条回答
不美不萌又怎样
2楼-- · 2019-01-04 15:47

The blocking tasks are not friendly with the event loop where the GUI is executed as they prevent the normal tasks that the GUI performs such as ticket checking, redrawing, etc. from being executed.

The solution in these cases is to use thread to execute the blocking task and use the signals to send the information.

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_())
查看更多
登录 后发表回答