为什么在app.quit()之后QWebEngineUrlRequestInterceptor仍然存在

时间:2019-07-07 06:06:24

标签: python pyqt pyqt5 qtwebengine

我有一个带有QWebEngineUrlRequestInterceptor的PyQt5 QWebEnginePage。运行app.exec_()之后,拦截器将按预期工作,但是在页面完成加载后,即回调  在self.loadFinished.connect(self._on_load_finished)中执行并运行self.app.quit()时,再次调用QWebEngineUrlRequestInterceptor.interceptRequest()函数,从而导致错误Received signal 11 <unknown> 000000000000 和脚本崩溃。

class WebEngineUrlRequestInterceptor(QWebEngineUrlRequestInterceptor):
    def __init__(self, on_network_call):
        super().__init__()
        self.on_network_call = on_network_call

    def interceptRequest(self, info):
        self.on_network_call(info)


class PyQtWebClient(QWebEnginePage):
  def __init__(self, url):
    self.app = QApplication(sys.argv)

    interceptor = WebEngineUrlRequestInterceptor(self.on_network_call)
    profile = QWebEngineProfile()
    profile.setRequestInterceptor(interceptor)

    super().__init__(profile, None)

    self.loadFinished.connect(self._on_load_finished)
    self.html = ""

    self.network_requests = {}

    self.load(QUrl(url))
    self.app.exec_()

  def on_network_call(self, info):
    # Something ...


  def _on_load_finished(self):
    self.toHtml(self.callable)

  def callable(self, html_str):
    self.html = html_str
    self.app.quit()

尝试过PyQt5.11.2PyQt5.10.1 我期望两件事之一: -如果页面上仍有待处理的请求,则不应调用self.loadFinished。 -如果调用self.loadFinished并且我的应用存在,则拦截器的线程应停止。

1 个答案:

答案 0 :(得分:3)

loadFinished表示页面内容已按照文档指示完成加载:

  

无效QWebEnginePage :: loadFinished(布尔确定)

     

当页面完成内容加载时,将发出此信号。这个   信号独立于脚本执行或页面呈现。好的会   指示加载成功还是发生任何错误。

但这并不意味着页面不断发出请求,例如您可以通过AJAX发出请求,因此请不要混淆这些概念。

如果QWebEngineUrlRequestInterceptor可以解决待处理的请求,因为该部分不是由Qt处理,而是由铬处理。

我在您的代码中看到的一个问题是,在销毁QWebEnginePage引起问题之前,销毁了QWebEngineProfile。这种情况下的解决方案是使类的配置文件和拦截器成员。

class PyQtWebClient(QWebEnginePage):
    def __init__(self, url):
        self.app = QApplication(sys.argv)

        self.interceptor = WebEngineUrlRequestInterceptor(self.on_network_call)
        self.profile = QWebEngineProfile()
        self.profile.setRequestInterceptor(self.interceptor)

        super().__init__(self.profile, None)
        # ...

最后,我建议使用最新版本的PyQt5 5.13.0PyQtWebEngine 5.13.0,因为它带来了诸如线程安全和特定于页面的URL请求拦截器之类的改进。