PyQt4中QWebView的多线程

Posted

技术标签:

【中文标题】PyQt4中QWebView的多线程【英文标题】:multiple threads of QWebView in PyQt4 【发布时间】:2012-12-19 00:07:23 【问题描述】:

情况如下: 我有一个加载特定 url 的类,还有一个参数列表,我需要发送到这个 url。我想使用线程“同时”加载这个 url,换句话说,不是加载一个 QWebView ,而是完成它而不是加载另一个我想一次打开 5 个窗口的窗口。

好的,所以现在的问题是,每个窗口都有不同的速度,所以我需要跟踪正在使用的参数。

例如:

params = [1,2,3,4,5,6,7]
a = MyClass(1)
b = MyClass(2)
c = MyClass(3)

现在如果假设 b 类在其他 2 个类之前完成,它将获得值 4,然后重新开始。

这是示例代码:

#! /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_() 

我很确定我需要使用线程、ether python native 线程或 PyQt4 QThread。

【问题讨论】:

不确定它是如何在 Python/PyQt 中实现的,但听起来你所需要的是一个队列结构,你可以调用 pop() 来每次结束时获取下一个值Grabber 完成了它的工作。只需确保将对 pop() 的调用包装在某种线程锁(例如互斥锁)中,以便一次只有一个线程尝试调用 pop。不是真正的答案(因此在评论中),但应该给你一些条款谷歌的解决方案;) 谢谢,没想到,但声音很棒 @Vor 查看我的答案,我对其进行了编辑以返回 grabber 对象 【参考方案1】:

看看这样的事情是否有效。这个bookie 类所做的是将loadFinished 调用的次数存储到变量count 中,并返回列表params 中的对应项。在创建grabber 对象时,它通过QSignalMapper 将其映射到一个数字,因此您可以通过调用mapper.mapping(id-of-grabber-object) 来检索信号的发送者。您可以继续尝试此代码,看看它是否适合您,然后再修改您的代码:

#!/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()

【讨论】:

非常感谢您的精彩回答! 你能看一下,我做错了什么,我开了一个新问题,因为不想让我的更新太长,所以这里是问题:http://***.com/questions/13960040/open-multiple-webpages-with-different-parametrs-pyqt4

以上是关于PyQt4中QWebView的多线程的主要内容,如果未能解决你的问题,请参考以下文章

PyQt4 QWebView 外部资源内容

使用 PyQt4 显示 HTML 页面时出错 - QWebView

如何让 QWebView 释放线程?

PyQt4.QtWebKit:加载停止时 QWebPage QWebView 设置超时

VB中的多线程

Python中的多线程并行运行