How to know when a web page is loaded when using QtWebKit?

白昼怎懂夜的黑 提交于 2019-11-27 07:19:49

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!

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

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"

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!