[Interest] Qt 5 -> 6: In QQmlEngine, Qt.Checked, etc. are no longer available

Thorbjørn Lindeijer bjorn at lindeijer.nl
Fri Jun 24 11:00:13 CEST 2022

Dear Ulf,

On Thu, Jun 23, 2022, at 23:21, Ulf Hermann wrote:
> In Qt5 if we have a QQmlEngine, each and every Qt namespace enum value 
> is added as a property to the Qt object, keyed by a newly created 
> QString, wrapped into a JS string, and the whole thing every time you 
> query one of those enums (until you query something that doesn't exist). 
> You may guess why I've removed this particular piece of code.

I fully understand why it would be desirable to remove such a kludge, though I might have expected a bit more consideration for applications that relied on these values. But maybe my use-case is pretty rare. Thanks a lot for your elaborate explanation and the suggested workarounds!

> If you want to work around the problem, there are a number of ways to 
> extend the JavaScript environment. For example:
>      QJSEngine engine;
>      engine.installExtensions(QJSEngine::AllExtensions);
>      engine.globalObject().setProperty(
>                  QStringLiteral("QtNamespace"),
>                  engine.newQMetaObject(&Qt::staticMetaObject));
>      engine.evaluate(QStringLiteral("console.log(QtNamespace.Checked)"));

That worked, thanks! However, for compatibility I really need both the functions and the enums, so I also tried the neat trick:

>      QJSEngine engine;
>      engine.installExtensions(QJSEngine::AllExtensions);
>      QJSValue qtObject = engine.globalObject().property("Qt");
>      QJSValue qtNamespace = engine.newQMetaObject(&Qt::staticMetaObject);
>      qtNamespace.setPrototype(qtObject);
>      engine.globalObject().setProperty("Qt", qtNamespace);
>      engine.evaluate(QStringLiteral("console.log(Qt.Checked)"));

This is very promising, but unfortunately I could only get it to work with QJSEngine and not with QQmlEngine. With the latter, the Qt object stubbornly still only provides various functions.

I'm relying on QQmlEngine rather than a QJSEngine, because only the QQmlEngine provides basic functions to control where output goes, like QQmlEngine::setOutputWarningsToStandardError (which I use to disable this) and the QQmlEngine::warnings signal (which I use to route any JS errors to a Console window inside the application).

Would there be any way to get this working with a QQmlEngine?

Alternatively, I guess I could open a feature request for the errors/warnings related API to be made available at the QJSEngine level. Though I would eventually like to support loading QML extensions as well.

> Now, it wouldn't be all that hard to do the above prototype trick 
> already when adding the Qt object to the JS global object. I need to 
> check if it opens new compatibility pitfalls, though.

That'd be nice, and hopefully it would work for both QJSEngine and QQmlEngine. But yeah, it's a bit hard to foresee the consequences.


More information about the Interest mailing list