Important: Please read the Qt Code of Conduct -

Custom C++ types and QJSEngine

  • Hi there,

    I'm converting a project from using QtScript to the new declarative engine. My goal is to be able to utilize QML when this is done, and use the same script context for the existing scripts and the QML. I've been able to convert pretty much everything relatively easily, but there's one thing I cannot find out.

    In QtScript there's the qScriptRegisterMetaType() function that registers custom types using custom conversion functions. This would allow me to register the following class for example:

    @class Point3D {

        int x;
        int y;
        int z;
        Point3D() = default;
        Point3D(int x, int y, int z);
        bool operator==(const Point3D &other) const;
        bool operator!=(const Point3D &other) const;
        Point3D operator+(const Vector3D &vector) const;
        Point3D operator-(const Vector3D &vector) const;
        Vector3D operator-(const Point3D &other) const;
        QString toString() const;
        static QScriptValue toScriptValue(QScriptEngine *engine, const Point3D &point);
        static void fromScriptValue(const QScriptValue &object, Point3D &point);


    The last two functions were passed to qScriptRegisterMetaType() and would do the actual conversion, which in this case converted the point to a JS array with 3 elements. Important to note is that the Point3D class does not inherit from QObject; it's a POD.

    Does anyone know if this is possible to achieve with QJSEngine as well? The only relevant function I found thus far -- qmlRegisterType() -- only works with QObject-based classes. Converting all types to QObject is really not an option for me and to make matters worse, I even have some QObject-based classes that will still need custom conversion functions as the conversion is more complex than a simple call to QJSEngine::newQObject().

    Arend jr.

    PS.: I'd really wish some of the more advanced options of QScriptEngine::newQObject() were available with QJSEngine::newQObject() as well...

  • Since there were no replies, and I don't think such custom types are supported as of yet, I created a corresponding bug report:

  • Hi,

    Sorry, I'm not too familiar with the QJSEngine stuff. With QML2 we now allow (via an undocumented interface) modules to provide their own value-types. These types are "QVariant-storable types which have sub-properties" such as QFont, QVector3D and so forth. Take a look at the valuetype related code in QtQuick2 - basically it registers a bunch of types as value types, provides load/store/copy/remove and conversion functions, etc.

    It's not too clean, there are hideous dragons in that code, and the interfaces are completely undocumented because they're really still meant for internal use only, but if you want to see how we did it, please feel free to check it out and try to provide your own in your own module.

    What we don't allow is any form of operator overloading. Hence, the valuetype mediator classes I implemented had a bunch of Q_INVOKABLE functions (for things like add/sub/mul etc).


Log in to reply