当我将它与 Selenium 一起使用时,PyQt 进度条不起作用
PyQt QProgressBar not working when I use it with Selenuim
我构建了一个 PyQt5 GUI 来进行一些 Selenium 测试。除了 PyQt 进度条外,一切都按预期工作。
在下面的第一个示例中,我使用的是 Selenium 浏览器,进度条刚好跳到 100%,最后,当浏览器关闭时。但是,Selenium 按预期工作。
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()
但是,在下面的这个版本中,在 Selenium 浏览器被注释掉的情况下,进度条可以正常工作。
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()
阻塞任务对执行 GUI 的事件循环不友好,因为它们会阻止执行 GUI 执行的正常任务,例如检票、重绘等。
这些情况的解决方案是使用线程执行阻塞任务并使用信号发送信息。
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_())
我构建了一个 PyQt5 GUI 来进行一些 Selenium 测试。除了 PyQt 进度条外,一切都按预期工作。
在下面的第一个示例中,我使用的是 Selenium 浏览器,进度条刚好跳到 100%,最后,当浏览器关闭时。但是,Selenium 按预期工作。
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()
但是,在下面的这个版本中,在 Selenium 浏览器被注释掉的情况下,进度条可以正常工作。
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()
阻塞任务对执行 GUI 的事件循环不友好,因为它们会阻止执行 GUI 执行的正常任务,例如检票、重绘等。
这些情况的解决方案是使用线程执行阻塞任务并使用信号发送信息。
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_())