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?
views:
1169answers:
4How are you defining completely loaded?
Is a page completely loaded when no ajax code is currently running? (Even if ajax code might run in the future?)
Is a page completely loaded when no ajax code will run in the future?
What would you do differently having this information? (Why does it matter?)
@Bill
Is a page completely loaded when no ajax code is currently running? (Even if ajax code might run in the future?)
Yes. In my case if there is an ajax call it's only one call per page triggered when user submits a form. No timers, not further ajax calls.
Is a page completely loaded when no ajax code will run in the future?
See my answer to the first question.
What would you do differently having this information? (Why does it matter?)
See my answer to the first question.
I have to extract data when it's loaded so I have to know when it's finished loading.
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...
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!