我有一个带有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.2
和PyQt5.10.1
我期望两件事之一:
-如果页面上仍有待处理的请求,则不应调用self.loadFinished。
-如果调用self.loadFinished并且我的应用存在,则拦截器的线程应停止。
答案 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.0和PyQtWebEngine 5.13.0,因为它带来了诸如线程安全和特定于页面的URL请求拦截器之类的改进。