PyQt进度在启动后跃升至100%

当我在doWork方法中运行代码时,通过点击button1,进度条将按预期工作。

然而,当我通过列表中的doWork其他方法的方法(即btn2btn3),进度条刚跳到100%它启动后。

from PyQt5 import QtCore, QtGui, QtWidgets

from PyQt5.QtWidgets import *

from PyQt5.QtCore import *

from PyQt5.QtGui import *

import sys

from selenium import webdriver

class SeleniumWorker(QtCore.QObject):

progressChanged = QtCore.pyqtSignal(int)

def doWork(self, lst=['http://www.somesite.com/',

'http://www.somesite.com/page2',

'http://www.somesite.com/page3']):

progress = 0

browser = webdriver.Firefox()

links = lst

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)

button1 = QtWidgets.QPushButton("Start1")

button2 = QtWidgets.QPushButton("Start2")

button3 = QtWidgets.QPushButton("Start3")

lay.addWidget(progressBar)

lay.addWidget(button1)

lay.addWidget(button2)

lay.addWidget(button3)

self.thread = QtCore.QThread()

self.worker = SeleniumWorker()

self.worker.moveToThread(self.thread)

self.thread.started.connect(self.worker.doWork)

button1.clicked.connect(self.thread.start)

button2.clicked.connect(self.btn2)

button3.clicked.connect(self.btn3)

self.worker.progressChanged.connect(progressBar.setValue)

def btn2(self):

self.lst2 = ['http://www.somesite.com/page4',

'http://www.somesite.com/page5',

'http://www.somesite.com/page6']

self.worker.doWork(self.lst2)

def btn3(self):

self.lst3 = ['http://www.somesite.com/page7',

'http://www.somesite.com/page8',

'http://www.somesite.com/page9']

self.worker.doWork(self.lst3)

if __name__ == '__main__':

app = QtWidgets.QApplication(sys.argv)

w = Widget()

w.show()

sys.exit(app.exec_())

回答:

看来您不了解我先前解决方案的逻辑,我将详细说明该过程:

[1] self.thread = QtCore.QThread()

[2] self.worker = SeleniumWorker()

[3] self.worker.moveToThread(self.thread)

[4] self.worker.progressChanged.connect(progressBar.setValue, QtCore.Qt.QueuedConnection)

[5] self.thread.started.connect(self.worker.doWork)

  1. QThread 是线程处理程序,因此该类的对象使我们可以在除主线程(称为GUI线程)之外的其他线程上执行任务。

  2. 您正在创建一个具有doWork方法的SeleniumWorker对象,该对象是不应在GUI线程中执行的阻塞任务,并且将使用先前的QThread来实现。

  3. 由于该函数必须在另一个线程中执行,因此具有该方法的对象必须移至该另一个线程。

  4. 另一个线程中的对象的信号连接到QProgressBarGUI线程中的对象,该连接必须使用flag进行QtCore.Qt.QueuedConnection

  5. 当线程启动时,它将调用doWork函数,并且由于self.worker对象在另一个线程中,因此该函数也将在另一个线程中执行。


对于您在下一部分显示的代码中,您doWork在线程尚未启动时正在调用该函数,因此它将在主线程中执行。

def btn2(self):

...

# main thread

self.worker.doWork(self.lst2)


传递url的一种方法是通过setter方法,然后启动线程。线程启动时,将调用doWorkdoWork执行时,将progressChanged发出信号。

通过以上所有操作,我们获得了以下内容:

import sys

from PyQt5 import QtCore, QtGui, QtWidgets

from selenium import webdriver

class SeleniumWorker(QtCore.QObject):

progressChanged = QtCore.pyqtSignal(int)

started = QtCore.pyqtSignal()

finished = QtCore.pyqtSignal()

def setUrls(self, urls=['http://www.somesite.com/',

'http://www.somesite.com/page2',

'http://www.somesite.com/page3']):

self.urls = urls

def doWork(self):

self.started.emit()

progress = 0

self.progressChanged.emit(progress)

browser = webdriver.Firefox()

links = self.urls

for link in links:

browser.get(link)

progress += 100 / len(links)

self.progressChanged.emit(progress)

browser.close()

self.finished.emit()

class Widget(QtWidgets.QWidget):

def __init__(self, *args, **kwargs):

QtWidgets.QWidget.__init__(self, *args, **kwargs)

lay = QtWidgets.QHBoxLayout(self)

self.progressBar = QtWidgets.QProgressBar()

self.progressBar.setRange(0, 100)

button1 = QtWidgets.QPushButton("Start1")

button2 = QtWidgets.QPushButton("Start2")

button3 = QtWidgets.QPushButton("Start3")

lay.addWidget(self.progressBar)

lay.addWidget(button1)

lay.addWidget(button2)

lay.addWidget(button3)

self.thread = QtCore.QThread()

self.worker = SeleniumWorker()

self.worker.moveToThread(self.thread)

self.worker.progressChanged.connect(self.progressBar.setValue, QtCore.Qt.QueuedConnection)

self.thread.started.connect(self.worker.doWork)

button1.clicked.connect(self.btn1)

button2.clicked.connect(self.btn2)

button3.clicked.connect(self.btn3)

self.worker.finished.connect(self.on_finished)

self.worker.started.connect(lambda: self.buttons_setEnable(False))

def on_finished(self):

self.buttons_setEnable(True)

if self.thread.isRunning():

self.thread.quit()

self.thread.wait()

def buttons_setEnable(self, enable):

for btn in self.findChildren(QtWidgets.QPushButton):

btn.setEnabled(enable)

def btn1(self):

self.worker.setUrls()

self.thread.start()

def btn2(self):

lst2 = ['http://www.somesite.com/page4',

'http://www.somesite.com/page5',

'http://www.somesite.com/page6']

self.worker.setUrls(lst2)

self.thread.start()

def btn3(self):

lst3 = ['http://www.somesite.com/page7',

'http://www.somesite.com/page8',

'http://www.somesite.com/page9']

self.worker.setUrls(lst3)

self.thread.start()

if __name__ == '__main__':

app = QtWidgets.QApplication(sys.argv)

w = Widget()

w.show()

sys.exit(app.exec_())

:我添加了在按钮运行时禁用按钮的功能,因为适当的是,线程在运行时不要再次启动。

以上是 PyQt进度在启动后跃升至100% 的全部内容, 来源链接: utcz.com/qa/408620.html

回到顶部