无论是 QWebFrame
还是 QWebPage
都有一个名为 void loadFinished(bool ok)
的信号,可以用于检测网页何时完全加载完成。但问题在于,当网页存在异步加载内容(ajax)时,如何知道网页何时完全加载完成呢?
无论是 QWebFrame
还是 QWebPage
都有一个名为 void loadFinished(bool ok)
的信号,可以用于检测网页何时完全加载完成。但问题在于,当网页存在异步加载内容(ajax)时,如何知道网页何时完全加载完成呢?
我实际上还没有做过这个,但我认为您可以使用QNetworkAccessManager
来实现您的解决方案。
您可以使用networkAccessManager()函数从您的QWebPage中获取QNetworkAccessManager。 QNetworkAccessManager有一个finished ( QNetworkReply * reply )信号,每当QWebPage实例请求文件时都会触发该信号。
finished
信号会给您一个QNetworkReply实例,您可以从中获取原始请求的副本,以识别该请求。
因此,创建一个插槽以附加到finished
信号,使用传入的QNetworkReply的方法来找出刚刚完成下载的文件是哪个,如果它是您的Ajax请求,则执行所需的任何处理。
我的唯一警告是我以前从未做过这件事,所以我不能保证它会起作用。
另一种选择可能是使用QWebFrame的方法将对象插入到页面的对象模型中,并插入一些JavaScript,然后在Ajax请求完成时通知您的对象。这是一种稍微有点hack的方法,但肯定可以工作。
编辑:
第二个选项对我来说似乎更好。工作流程如下:
将一个槽附加到QWebFrame :: javascriptWindowObjectCleared()信号。此时,调用QWebFrame :: evaluateJavascript()添加类似以下代码的代码: window.onload = function() { // page has fully loaded }
在该函数中放置所需的任何代码。您可能希望通过QWebFrame :: addToJavaScriptWindowObject()向页面添加QObject,然后调用该对象上的函数。此代码仅在页面完全加载时执行。
希望这回答了问题!
要检查特定元素的负载,您可以使用 QTimer
。在 Python 中可以像这样实现:
@pyqtSlot()
def on_webView_loadFinished(self):
self.tObject = QTimer()
self.tObject.setInterval(1000)
self.tObject.setSingleShot(True)
self.tObject.timeout.connect(self.on_tObject_timeout)
self.tObject.start()
@pyqtSlot()
def on_tObject_timeout(self):
dElement = self.webView.page().currentFrame().documentElement()
element = dElement.findFirst("css selector")
if element.isNull():
self.tObject.start()
else:
print "Page loaded"
当你的初始HTML、图片等加载完成后,就完成了。这个事实不会改变,即使你之后决定使用一些JavaScript来获取一些额外的数据、页面浏览或其他。
话虽如此,我猜想你想要在此处执行的是向视图公开一个QtScript对象/接口,以便你可以从你网页的脚本中调用它,从而提供一个“回调”到你的C++,一旦你已经决定(从页面脚本)已经“完全加载”了。
希望这能给你一个尝试的方向...
原帖作者认为这是由于延迟的 AJAX 请求导致的,但也可能有另一个原因可以解释为什么非常短的时间延迟可以解决问题。存在一个导致所描述行为的错误:
为了解决这个问题,必须使用排队连接来连接loadingFinished()信号。loadFinished()
信号发出之前保证完成了什么,唯一可靠的解决方案是使用Rob Knight建议的window.onload
。无论如何,由于QtWebKit的开发已经被QtWebEngine取代,我不会指望有任何改变。 - Piotr Dobrogost
onload
事件上。当它完成后,我认为页面已经完全加载。 - Piotr Dobrogost