Search code examples
qtqwebviewqwebengineviewqwebengine

QWebEngine: Execute runJavascript synchronously - QEventLoop blocks Javascript calls


Using Qt 5.15.2 - Execute runJavascript synchronously.

Problem:

I tried QtWebEngine - synchronously execute JavaScript to read function result as a separate application and it worked fine, everything works as expected. But in my project on eventLoop->exec(), JS function is not executed(runJavascript is called).

QSharedPointer<QEventLoop> loop = QSharedPointer<QEventLoop>(new QEventLoop());
 req.get()->m_pWebEngineView->page()->runJavaScript(req.get()->m_strJSFuncSignature, [loop](const QVariant& val) {
                    if (loop->isRunning()) {
                        loop->quit();
                    }
                    });
  loop->exec(QEventLoop::AllEvents | QEventLoop::WaitForMoreEvents);

Description:

We are creating a SINGLE-THREADED application that reads an XML file and creates HTML/Js/Css UI. I'm using CSS flex layout to layout the UI items. In code, I want to get the computed size and position synchronously in cpp.

To achieve synchronous communication to Javascript, I used the local event loop technique mentioned in QtWebEngine - synchronously execute JavaScript to read function result. The application hangs, Js function is not at all called.

Observation:

Without QEventLoop, all runjavascript calls are executed successfully one-after-other at the end i.e after all the statements in the program are executed.

With QEventLoop, all runjavascript calls are called but corresponding Js functions are not executed. Application hangs because runjavascript callback is not called.

Why this is happening? Kindly help.


Solution

  • Found the problem. I was starting local QtEventLoop in the cpp function which is called from JS. The local QEventLoop in cpp function never quits because the Js function called in local QEventLoop is waiting for the current Js call to finish. Kind of deadlock.

    Solution: I queued the call coming from Js to cpp to global event loop.