问题
Here is the situation: I have a class that loads specific url, also have a list of parameters, that I need to send to this url. I want to use threads to load this url kinda 'simultaneously', in other words in stead of loading one QWebView , than finish it than load another one I want to open 5 windows at a time.
OK, So now the problem is, every single window will have different speed, so I need to keep track of what parametrs are in use.
for example:
params = [1,2,3,4,5,6,7]
a = MyClass(1)
b = MyClass(2)
c = MyClass(3)
now if lets say class b has finished befoure other 2 classes, it will get value 4, and will start it again.
And this is sample code:
#! /usr/bin/env python2.7
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4.QtWebKit import *
import sys, signal
class Grabber(QWebView):
def __init__(self, param=None):
QWebView.__init__(self)
self.loadFinished.connect(self._loadComplete)
url = QUrl('http://some website.com/search?param=%s'%param)
self.load(url)
self.show()
def _loadComplete(self):
print "Done"
if __name__ == "__main__":
app = QApplication(sys.argv)
# Dont know what to do with the next 2 lines
thread_pool = QThreadPool()
thread_pool.setMaxThreadCount(10)
param = [1,2,3,4,5,6,7,8,9,10,11,12] # and so on
# Whant to achive something similar:
for i in param:
a = Grabber(i)
b = Grabber(i)
c = Grabber(i)
d = Grabber(i)
e = Grabber(i)
if signal.signal(signal.SIGINT, signal.SIG_DFL):
sys.exit(app.exec_())
app.exec_()
I'm pretty sure I need to use threads, ether python native threads or PyQt4 QThread.
回答1:
See if something like this works. What this bookie class does is store the number of times loadFinished is called into the variable count, and returns the corresponding item in the list params. When creating the grabber objects, it maps it to a number through QSignalMapper, so you may retrieve the sender of the signal by calling mapper.mapping(id-of-grabber-object). You can go ahead and try this code to see if it works for you before modifying yours:
#!/usr/bin/env python
from PyQt4.QtCore import pyqtSlot, QObject, QSignalMapper, QTimer
from PyQt4.QtGui import QApplication
from PyQt4.QtWebKit import QWebView
class bookie(QObject):
def __init__(self, parent=None):
super(bookie, self).__init__(parent)
self.count = 0
self.url = 'http://some website.com/search?param={0}'
self.params = range(100) # instead of [1,2,3,4,5,6,7,8,9,10,11,12] and so on...
Grabber = QWebView # This would be your Grabber class
self.mapper = QSignalMapper(self)
self.mapper.mapped.connect(self.on_mapper_mapped)
for grabberNumber in range(10): # Create 10 Grabber instances
grabber = Grabber()
grabber.loadFinished.connect(self.mapper.map)
self.mapper.setMapping(grabber, grabberNumber)
grabber.loadFinished.emit(True) # Initialize the grabber by emitting loadFinished
def on_mapper_mapped(self, gNumber):
self.count += 1
if self.count < len(self.params):
gParam = self.params[self.count]
grabber = self.mapper.mapping(gNumber)
#grabber.load(QUrl(self.url.format(gParam)))
# Next 2 lines for testing purposes, remove & uncomment the previous line
print "GRABBER:", gNumber, "PARAMETER:", gParam
QTimer.singleShot(1, lambda:grabber.loadFinished.emit(True))
if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
main = bookie()
来源:https://stackoverflow.com/questions/13943558/multiple-threads-of-qwebview-in-pyqt4