python - PySide 浏览器位于单独的进程中

标签 python qt inheritance processing pyside

我尝试编写一个简单的解析器,它检查一些网页,如果这些页面上的内容发生更改,则脚本将 url 发送到 headless webkit 浏览器,该浏览器使用 PySide 绑定(bind)到 Qt 运行并生成屏幕截图。我希望这个浏览器始终在后台单独的进程中运行,等待 url 出现在队列中。一旦url到来,它就会截图,保存,然后返回等待。

我尝试用此代码实现此行为(我剪切了解析器部分):

import multiprocessing
import sys
from datetime import datetime
from PySide import QtGui, QtWebKit, QtCore

class Browser(QtWebKit.QWebPage):
    def __init__(self, queue_in, queue_out):
        self.app = QtGui.QApplication(sys.argv)
        QtWebKit.QWebPage.__init__(self)
        self.queue_out = queue_out
        self.queue_in = queue_in
        self.setViewportSize(QtCore.QSize(900, 900))
        self.mainFrame().setScrollBarPolicy(QtCore.Qt.Horizontal, QtCore.Qt.ScrollBarAlwaysOff)
        self.mainFrame().setScrollBarPolicy(QtCore.Qt.Vertical, QtCore.Qt.ScrollBarAlwaysOff)
        self.mainFrame().loadFinished.connect(self._makeScreenshot)
        self.makeScreenshotOf()

    def makeScreenshotOf(self):
        self.mainFrame().setUrl(QtCore.QUrl.fromEncoded(self.queue_in.get()))

    def _makeScreenshot(self):
        image = QtGui.QImage(self.viewportSize(), QtGui.QImage.Format_ARGB32)
        painter = QtGui.QPainter(image)
        self.mainFrame().render(painter)
        painter.end()
        file_name = datetime.now().strftime("%Y-%m-%d %H-%M-%S-%f") + ".png"
        image.save(file_name)
        self.queue_out.put(file_name)
        self.makeScreenshotOf()

if __name__ == "__main__":
    multiprocessing.set_start_method('spawn')
    queue_in = multiprocessing.Queue()
    queue_out = multiprocessing.Queue()
    t = threading.Thread(target = Browser, args = (queue_in, queue_out))
    t.start()
    queue_in.put(url)

问题是,在第一次运行时,进程成功保持搁置,等待 url 出现在队列中,但一旦获取 url,进程就会停止,忽略 Qt 连接

self.mainFrame().loadFinished.connect(self._makeScreenshot)

问题是,如果我直接从 Process 继承

class Browser(multiprocessing.Process):
    def __init__(self, queue_in, queue_out):
        multiprocessing.Process.__init__(self)
        self.queue_out = queue_out
        self.queue_in = queue_in
        self.app = QtGui.QApplication(sys.argv)
        self.browser = QtWebKit.QWebPage()
        ...
if __name__ == "__main__":
    queue_in = multiprocessing.Queue()
    queue_out = multiprocessing.Queue()
    b = Browser(queue_in, queue_out)

然后连接不会被忽略,并且一切正常,但作为副作用 self.queue_in.get() 在浏览器进程中调用也会阻塞主进程(如果队列为空)。

问题:

  1. 为什么 Qt 连接在第一种情况下不起作用,而在另一种情况下却工作?
  2. 为什么在第二种情况下,queue.get() 会阻塞主进程?如何防止这种情况发生?

最佳答案

如果队列为空,

Queue.get() 会阻塞。使用get_nowait() ,如果那里没有任何内容,则会引发异常。

关于python - PySide 浏览器位于单独的进程中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25587772/

相关文章:

python - 我在 Python 的 itertools 中找不到 imap()

Python Selenium 返回文本,unicode 对象不可调用

Python - 将字符串和转义的十六进制字符串数据转换为整数的更好方法?

python - py2exe 的相对导入错误

c++ - 在 Qt 5.5 中持续检查主循环

c++ - 编辑 QTableWidgetItem 时捕获 ESC 键

c++ - 在类中初始化QHash

c++ - C++ 中派生类的等式测试

perl - 如何让所有继承的方法返回子类对象?

javascript - 在 HOC 中访问 React 组件的功能