使用 QtWebKit 时如何知道网页何时加载?

发布于 2024-08-02 12:43:59 字数 155 浏览 4 评论 0原文

QWebFrameQWebPage 都有 void loadFinished(bool ok) 信号,可用于检测网页何时完全加载。问题是当网页异步加载某些内容(ajax)时。在这种情况下如何知道页面何时完全加载?

Both QWebFrame and QWebPage have void loadFinished(bool ok) signal which can be used to detect when a web page is completely loaded. The problem is when a web page has some content loaded asynchronously (ajax). How to know when the page is completely loaded in this case?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

眉黛浅 2024-08-09 12:44:00

我实际上还没有这样做,但我认为您也许能够使用QNetworkAccessManager实现您的解决方案。

您可以使用 networkAccessManager() 函数从 QWebPage 获取 QNetworkAccessManager。 QNetworkAccessManager 有一个信号 finished ( QNetworkReply *reply ) 每当文件被调用时就会触发该信号由 QWebPage 实例请求。

finished 信号为您提供一个 QNetworkReply 实例,您可以从中获取原始请求的副本,以便识别该请求。

因此,创建一个插槽来附加到 finished 信号,使用传入的 QNetworkReply 方法来确定哪个文件刚刚完成下载,如果是您的 Ajax 请求,则执行您需要执行的任何处理。

我唯一需要注意的是,我以前从未这样做过,所以我不能 100% 确定它会起作用。

另一种选择可能是使用 QWebFrame 的方法将对象插入到页面的对象模型中,并插入一些 JavaScript,然后在 Ajax 请求完成时通知您的对象。这是一种稍微有点黑客的方法,但绝对应该有效。

编辑:

第二个选项对我来说似乎更好。工作流程如下:

将一个槽附加到 QWebFrame::javascriptWindowObjectCleared() 信号。此时,调用QWebFrame::evaluateJavascript()添加类似如下的代码:
window.onload = function() { // 页面已完全加载 }

将您需要的任何代码放入该函数中。您可能想通过 QWebFrame::addToJavaScriptWindowObject() 将 QObject 添加到页面,然后调用该对象上的函数。该代码仅在页面完全加载时执行。

希望这能回答这个问题!

I haven't actually done this, but I think you may be able to achieve your solution using QNetworkAccessManager.

You can get the QNetworkAccessManager from your QWebPage using the networkAccessManager() function. QNetworkAccessManager has a signal finished ( QNetworkReply * reply ) which is fired whenever a file is requested by the QWebPage instance.

The finished signal gives you a QNetworkReply instance, from which you can get a copy of the original request made, in order to identify the request.

So, create a slot to attach to the finished signal, use the passed-in QNetworkReply's methods to figure out which file has just finished downloading and if it's your Ajax request, do whatever processing you need to do.

My only caveat is that I've never done this before, so I'm not 100% sure that it would work.

Another alternative might be to use QWebFrame's methods to insert objects into the page's object model and also insert some JavaScript which then notifies your object when the Ajax request is complete. This is a slightly hackier way of doing it, but should definitely work.

EDIT:

The second option seems better to me. The workflow is as follows:

Attach a slot to the QWebFrame::javascriptWindowObjectCleared() signal. At this point, call QWebFrame::evaluateJavascript() to add code similar to the following:
window.onload = function() { // page has fully loaded }

Put whatever code you need in that function. You might want to add a QObject to the page via QWebFrame::addToJavaScriptWindowObject() and then call a function on that object. This code will only execute when the page is fully loaded.

Hopefully this answers the question!

怼怹恏 2024-08-09 12:44:00

要检查特定元素的负载,您可以使用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"

To check the load of specific element you can use a QTimer. Something like this in 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"
若相惜即相离 2024-08-09 12:44:00

当您的初始 html/images/etc 完成加载时,就这样了。它完全加载。如果您事后决定使用一些 javascript 来获取一些额外的数据、页面浏览量或其他任何内容,这一事实不会改变。

也就是说,我怀疑您想要在这里做的是向您的视图公开一个 QtScript 对象/接口,您可以从页面的脚本调用它,一旦您决定(从页面脚本),有效地向您的 C++ 提供“回调”你已经“完全加载”了。

希望这有助于为您提供尝试的方向...

When your initial html/images/etc finishes loading, that's it. It is completely loaded. This fact doesn't change if you then decide to use some javascript to get some extra data, page views or whatever after the fact.

That said, what I suspect you want to do here is expose a QtScript object/interface to your view that you can invoke from your page's script, effectively providing a "callback" into your C++ once you've decided (from the page script) that you've have "completely loaded".

Hope this helps give you a direction to try...

情深已缘浅 2024-08-09 12:44:00

OP 认为这是由于 AJAX 请求延迟造成的,但也可能有另一个原因可以解释为什么非常的时间延迟可以解决问题。有一个错误导致所描述的行为:

https://bugreports.qt-project.org /browse/QTBUG-37377

要解决此问题,必须使用排队连接来连接loadingFinished() 信号。

The OP thought it was due to delayed AJAX requests but there also could be another reason that also explains why a very short time delay fixes the problem. There is a bug that causes the described behaviour:

https://bugreports.qt-project.org/browse/QTBUG-37377

To work around this problem the loadingFinished() signal must be connected using queued connection.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文