Question

I'm using a QWebPage without a QWebView because I want to render the contents of an HTML file onto a QPixmap/QImage.

I want the loading of the page to be done synchronously, not asynchronously which is the default. The default way is to call QWebFrame::setHtml() or QWebFrame::setContent(), but this loads images asynchronously. What I want is some sort of blocking function call, something like QWebFrame::waitUntilLoadFinished() after which I could just call render() and be done with it.

I can't find a way to do this. Am I missing something?

Was it helpful?

Solution 4

If anyone's interested, I implemented this using a special "PageRasterizer" class.

The class creates a QWebPage in the constructor and sets a bool loading flag to false. A connect() call connects the loadFinished signal to a member slot that merely sets the loading flag to true.

A special RenderPage() member function that returns an image does all the work: it accepts the HTML string and calls setHtml(). After that comes a while loop that waits on the flag; while the flag is false, qApp->processEvents() is called so signals get emitted and the flag setting slot is eventually called. When it is, the loop breaks and now you can render the page to a QImage (don't forget to set the flag back to false before returning).

If you're interested in the rendering process, look at this Qt example (the Thumbnailer::render() function).

For bonus points, you can make this class a functor.

OTHER TIPS

If someone still needs it, this is how I got it working.

mWebPage->mainFrame()->setHtml("...");
QEventLoop loop;
connect(mWebPage,SIGNAL(loadFinished(bool)),&loop,SLOT(quit()));
loop.exec();
/* your webpage has finished loading & is ready to use */

I suggest you to do it the Qt way and do it async, it helps a lot.

In case you still want to do it in Sync, use QEventLoop in a seperate QThread.

See my comment for detailed QThread usage information. Note: do not forget to call moveToThread(); within the thread header, or all signals will go over the QApplication execution loop.

That approach has the problem that you basically have to wait for an undetermined amount of time and if you're issuing the call from the main thread you're blocking event processing and thus signals like loadFinished.

While you could get around that by explictly pumping event, i don't see an inherent problem that could prevent you from issuing the page-load and just do the processing when loadFinished occured.
If you need secondary threads to wait for the page, you could always let those threads wait by using synchronisation mechanisms.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top