如何在使用QtWebKit时知道何时加载web页面?

时间:2022-06-15 05:46:50

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?

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

4 个解决方案

#1


12  

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

实际上我还没有这样做,但是我认为您可以使用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.

您可以使用networkAccessManager()函数从您的qweb获得QNetworkAccessManager。QNetworkAccessManager有一个信号完成(QNetworkReply * reply),每当qweb实例请求文件时,该信号就被触发。

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.

完成的信号给您一个QNetworkReply实例,您可以从中获得原始请求的副本,以确定请求。

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.

因此,创建一个连接到已完成信号的插槽,使用传入的QNetworkReply的方法来计算刚刚完成下载的文件,如果是Ajax请求,则执行需要做的任何处理。

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.

另一种方法可能是使用QWebFrame的方法将对象插入到页面对象模型中,并插入一些JavaScript,当Ajax请求完成时,这些JavaScript会通知对象。这是一种稍微有点粗糙的方法,但是绝对可以。

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 }

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

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.

在这个函数中输入你需要的任何代码。您可能希望通过QWebFrame::: addtojavascritwindowobject()向页面添加QObject,然后调用该对象上的函数。此代码仅在页面完全加载时执行。

Hopefully this answers the question!

希望这能回答这个问题!

#2


1  

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.

当你的初始html/图像/等完成加载时,就完成了。这是完全加载。如果您决定使用javascript获取一些额外的数据、页面视图或其他内容,这个事实不会改变。

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".

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

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

希望这能给你一个尝试的方向。

#3


1  

To check the load of specific element you can use a QTimer. Something like this in python:

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

#4


0  

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:

OP认为这是由于延迟的AJAX请求造成的,但也有另一个原因可以解释为什么很短的时间延迟会修复问题。有一个bug导致了所描述的行为:

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

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

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

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

#1


12  

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

实际上我还没有这样做,但是我认为您可以使用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.

您可以使用networkAccessManager()函数从您的qweb获得QNetworkAccessManager。QNetworkAccessManager有一个信号完成(QNetworkReply * reply),每当qweb实例请求文件时,该信号就被触发。

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.

完成的信号给您一个QNetworkReply实例,您可以从中获得原始请求的副本,以确定请求。

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.

因此,创建一个连接到已完成信号的插槽,使用传入的QNetworkReply的方法来计算刚刚完成下载的文件,如果是Ajax请求,则执行需要做的任何处理。

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.

另一种方法可能是使用QWebFrame的方法将对象插入到页面对象模型中,并插入一些JavaScript,当Ajax请求完成时,这些JavaScript会通知对象。这是一种稍微有点粗糙的方法,但是绝对可以。

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 }

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

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.

在这个函数中输入你需要的任何代码。您可能希望通过QWebFrame::: addtojavascritwindowobject()向页面添加QObject,然后调用该对象上的函数。此代码仅在页面完全加载时执行。

Hopefully this answers the question!

希望这能回答这个问题!

#2


1  

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.

当你的初始html/图像/等完成加载时,就完成了。这是完全加载。如果您决定使用javascript获取一些额外的数据、页面视图或其他内容,这个事实不会改变。

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".

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

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

希望这能给你一个尝试的方向。

#3


1  

To check the load of specific element you can use a QTimer. Something like this in python:

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

#4


0  

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:

OP认为这是由于延迟的AJAX请求造成的,但也有另一个原因可以解释为什么很短的时间延迟会修复问题。有一个bug导致了所描述的行为:

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

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

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

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