Синхронная загрузка QtWebkit

Я использую QWebPage без QWebView, потому что хочу отображать содержимое HTML файла в QPixmap/QImage.

Я хочу, чтобы загрузка страницы выполнялась синхронно, а не асинхронно, что по умолчанию. По умолчанию используется вызов QWebFrame::setHtml() или QWebFrame::setContent(), но он загружает изображения асинхронно. Я хочу, это какой-то вызов функции блокировки, что-то вроде QWebFrame::waitUntilLoadFinished(), после чего я мог просто вызвать render() и сделать с ним.

Я не могу найти способ сделать это. Я что-то пропустил?

Ответ 1

Если кто-то заинтересован, я применил это, используя специальный класс "PageRasterizer".

Класс создает QWebPage в конструкторе и устанавливает флаг загрузки bool в значение false. A connect() соединяет сигнал loadFinished с слотом участника, который просто устанавливает флаг загрузки в значение true.

Специальная функция-член RenderPage(), которая возвращает изображение, выполняет всю работу: он принимает строку HTML и вызывает setHtml(). После этого появляется цикл while, который ждет флаг; в то время как флаг является ложным, qApp->processEvents() вызывается так, что сигналы выдаются, и слот установки флага в конечном итоге вызывается. Когда это произойдет, цикл прерывается, и теперь вы можете отобразить страницу в QImage (не забудьте вернуть флаг к false до возвращения).

Если вы заинтересованы в процессе рендеринга, посмотрите этот пример Qt (функция Thumbnailer::render()).

Для бонусных очков вы можете сделать этот класс функтором.

Ответ 2

Я предлагаю вам сделать это способом Qt и сделать это асинхронно, это очень помогает.

Если вы все еще хотите сделать это в Sync, используйте QEventLoop в отдельном QThread.

См. мой комментарий для подробной информации об использовании QThread. Примечание: не забудьте вызвать moveToThread(); в заголовке потока, или все сигналы будут проходить через цикл выполнения QApplication.

Ответ 3

Если кто-то все еще нуждается в этом, вот как я его работаю.

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

Ответ 4

У этого подхода есть проблема, что вам в основном приходится ждать неопределенного количества времени, и если вы выходите из основного потока, вы блокируете обработку событий и, таким образом, сигнализируете, как loadFinished.

Пока вы можете обойти это с помощью явного события накачки, я не вижу врожденной проблемы, которая может помешать вам загрузить загрузку страницы и просто выполнить обработку, когда произошел loadFinished.
Если вам нужны дополнительные потоки для ожидания страницы, вы всегда можете позволить этим потокам ждать с помощью механизмов синхронизации.