当我在doWork
方法中运行代码时,通过点击button1
,进度条将按预期工作。
然而,当我通过列表中的doWork
其他方法的方法(即btn2
,btn3
),进度条刚跳到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)
QThread
是线程处理程序,因此该类的对象使我们可以在除主线程(称为GUI线程)之外的其他线程上执行任务。
您正在创建一个具有doWork方法的SeleniumWorker对象,该对象是不应在GUI线程中执行的阻塞任务,并且将使用先前的QThread来实现。
由于该函数必须在另一个线程中执行,因此具有该方法的对象必须移至该另一个线程。
另一个线程中的对象的信号连接到QProgressBar
GUI线程中的对象,该连接必须使用flag进行QtCore.Qt.QueuedConnection
。
当线程启动时,它将调用doWork函数,并且由于self.worker对象在另一个线程中,因此该函数也将在另一个线程中执行。
对于您在下一部分显示的代码中,您doWork
在线程尚未启动时正在调用该函数,因此它将在主线程中执行。
def btn2(self):
...
# main thread
self.worker.doWork(self.lst2)
传递url的一种方法是通过setter方法,然后启动线程。线程启动时,将调用doWork
,doWork
执行时,将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_())
注意 :我添加了在按钮运行时禁用按钮的功能,因为适当的是,线程在运行时不要再次启动。
问题内容: 当我在方法中运行时,通过单击,进度条将按预期工作。 然而,当我通过列表中的其他方法的方法(即,),进度条刚跳到100%它启动后。 问题答案: 看来您不了解我先前解决方案的逻辑,我将详细说明该过程: 是线程处理程序,因此该类的对象使我们可以在除主线程(称为GUI线程)之外的其他线程上执行任务。 您正在创建一个具有doWork方法的SeleniumWorker对象,该对象是不应在GUI线程
我最近刚刚将团队的一个Spring Boot应用程序从2.1.3版升级到2.3.0版,并将Hibernate版本从5.3.6.final升级到5.4.15.final。 一切都很好,但是现在当应用程序在服务器上启动时,启动需要800-900秒(大约15分钟),而以前只需要30秒。 需要注意的是,当在localhost上运行2.1.3和2.3.0时,应用程序的启动是相同的,大约为12-15秒。 只有
PS Vita的系统软件可通过升级,追加各式各样的功能或强化安全性。使用时请随时升级为最新版本。 若要进行系统升级,需事先将连接的电脑设为以下状态。 连接互联网 安装/下载PlayStation®内容管理助手 可在以下网站进行下载。 http://cma.dl.playstation.net/cma/ 1. 在电脑确认内容管理助手是否已启动。 可从电脑的工作列确认。 2. 使用USB连接线连接PS
PS Vita的系统软件可通过升级,追加各式各样的功能或强化安全性。使用时请随时升级为最新版本。 若要进行升级,需事先将连接的PS3™设为以下状态。 连接互联网 系统软件升级为版本4.00以上 关闭所有使用中的应用程序,显示(用户) 1. 使用USB连接线连接PS Vita和PS3™。 2. 操作PS Vita,轻触[系统升级]>[连接至PS3™进行升级]。 可通过PS3™的网络功能,经由互联网下
我在周末将笔记本电脑从Kubuntu 12.04升级到12.10,一切看起来都很好,直到我重新开始工作。 笔记本电脑是一台通过php5 fpm运行Nginx和php的webdev机器,但现在看来php5 fpm不会启动。当我运行/etc/init时。d/php5 fpm重启我刚收到一条消息说失败。我在syslog或/var/log/fpm php中没有收到任何消息。www.log提供有关正在发生的
问题内容: 我有一个奇怪的场景,其中SQL Server 2012数据库中的自动标识int列未正确递增。 假设我有一个使用int自动标识作为主键的表,它偶尔会跳过增量,例如: 1,2,3,4,5,1004,1005 这是在非常随机的时间在随机数量的表上发生的,无法复制以找到任何趋势。 这是怎么回事?有没有办法使它停止? 问题答案: 这完全是正常的。微软在SQL Server 2012中添加了,最后