Синхронная загрузка QtWebkit
Вопрос
Я использую QWebPage без QWebView, потому что хочу визуализировать содержимое HTML-файла в QPixmap/QImage.
Я хочу, чтобы загрузка страницы происходила синхронно, нет асинхронно, что является значением по умолчанию.Способ по умолчанию — позвонить QWebFrame::setHtml()
или QWebFrame::setContent()
, но при этом изображения загружаются асинхронно.Мне нужен какой-то вызов функции блокировки, что-то вроде QWebFrame::waitUntilLoadFinished()
после чего я мог бы просто позвонить render()
и покончим с этим.
Я не могу найти способ сделать это.Я что-то пропустил?
Решение 4
Если кому-то интересно, я реализовал это с помощью специального класса PageRasterizer.
Класс создает QWebPage в конструкторе и устанавливает для логического флага загрузки значение false.А connect()
звонок соединяет loadFinished
сигнал в слот-член, который просто устанавливает флаг загрузки в значение true.
Специальный RenderPage()
функция-член, которая возвращает изображение, выполняет всю работу:он принимает строку HTML и вызывает setHtml()
.После этого наступает while
цикл, ожидающий флага;пока флаг ложный, qApp->processEvents()
вызывается, чтобы излучались сигналы и в конечном итоге вызывался слот установки флага.Когда это произойдет, цикл прерывается, и теперь вы можете визуализировать страницу в QImage (не забудьте перед возвратом установить флаг обратно в значение false).
Если вас интересует процесс рендеринга, посмотрите этот пример Qt ( Thumbnailer::render()
функция).
За бонусные баллы вы можете сделать этот класс функтором.
Другие советы
Если кому-то это еще нужно, то у меня это работает вот так.
mWebPage->mainFrame()->setHtml("...");
QEventLoop loop;
connect(mWebPage,SIGNAL(loadFinished(bool)),&loop,SLOT(quit()));
loop.exec();
/* your webpage has finished loading & is ready to use */
Я предлагаю вам сделать это способом Qt и сделать это асинхронно, это помогает много.
Если вы все еще хотите сделать это в синхронизации, используйте QEventLoop в отдельном QThread.
Подробную информацию об использовании QThread смотрите в моем комментарии.Примечание:не забудьте вызвать moveToThread();внутри заголовка потока, иначе все сигналы пройдут через цикл выполнения QApplication.
Проблема этого подхода заключается в том, что вам по сути приходится ждать неопределенное количество времени, и если вы отправляете вызов из основного потока, вы блокируете обработку событий и, таким образом, сигнализируете типа loadFinished
.
Пока ты мог обойти это, явно накачав событие, я не вижу внутренней проблемы, которая могла бы помешать вам выполнить загрузку страницы и просто выполнить обработку, когда loadFinished
произошло.
Если вам нужно, чтобы вторичные потоки ждали страницу, вы всегда можете позволить этим потокам подождать, используя механизмы синхронизации.