Typedefination of basic datatypes is not recognised in qml



  • Hi ,
    To Satisfy MISRA Coding Guidlines
    Guidline....
    3-9-2 Typedefs that indicate size and signedness should be used in place of the basic numerical types.

    the following function
    Q_INVOKABLE int getTemperature1(bool init=false) const;
    is rewritten as
    Q_INVOKABLE SINT getTemperature1(bool init=false) const;

    where SINT is a typedef
    but in qml I am getting this error
    Unknown method return type: SINT

    So what is to be done.
    Regards



  • @Phadnis No, this not possible with QML.

    To do this, you have to register to SINT type with qRegisterMetaType, this will enable QML engine to work with this new type.
    Take a look at https://doc.qt.io/qt-5/qtqml-cppintegration-data.html for more details.

    regards



  • The only types I think you can make in QML are QObject based types, at least that is all I can find.

    This would mean that in order to interface to QML you may have to use only QObject based types if you want to follow MISRA for your C++. Otherwise if you want to use basic types with QML you would have to break the rules.

    Are there exceptions for interfacing to systems that are inflexible?



  • Is SINT a typedef or can it be a #define? Does the rule mandate it must be a different type or that it just cannot be a naked "int" and could be a "#define SINT int" or something similar? The reason I ask is what is the intent? Is it to make it readable and recognizable or is there some reason it needs to be a different "type"? Because if SINT is defined like this: typedef int SINT, then the resulting code won't be any different than if you used a naked int. So it just becomes a readability issue and not a functionality issue. Using a #define gives you the readability without sacrificing the ability to pass an int to QML as it just gets replaces with int when compiling.



  • @fcarney You asked: "So what is to be done."

    Just add in you main.cpp

    qRegisterMetaType<SINT>("SINT")
    

    So QML engine will be aware about SINT type, and can work with.

    That's all.

    Have you tried this?



  • @KroMignon said in Typedefination of basic datatypes is not recognised in qml:

    qRegisterMetaType<SINT>("SINT")

    I looked all over for that. Where did you find that so I can bookmark the reference?



  • @fcarney said in Typedefination of basic datatypes is not recognised in qml:

    I looked all over for that. Where did you find that so I can bookmark the reference?

    Take at look at https://doc.qt.io/qt-5/custom-types.html and https://doc.qt.io/qt-5/qmetatype.html#qRegisterMetaType



  • @KroMignon said in Typedefination of basic datatypes is not recognised in qml:

    Take at look at https://doc.qt.io/qt-5/custom-types.html and https://doc.qt.io/qt-5/qmetatype.html#qRegisterMetaType

    Not sure that will work for "int".
    "Registers the type name typeName for the type T. Returns the internal ID used by QMetaType. Any class or struct that has a public default constructor, a public copy constructor and a public destructor can be registered."



  • @fcarney said in Typedefination of basic datatypes is not recognised in qml:

    Not sure that will work for "int".

    Why you are so resistant and don't try it out?

    I've done a little test class

    class MisraInfo : public QObject
    {
        Q_OBJECT
    
    public:
        explicit MisraInfo(QObject * parent = Q_NULLPTR) : QObject(parent)
        {
        }
    
        Q_INVOKABLE SINT touchMe()
        {
            static int counter = 0;
        
            return ++counter;
        }
    };
    

    And:

    int main(int argc, char *argv[])
    {
    ...
       MisraInfo misra;
       engine->rootContext()->setContextProperty("misra", &misra);
    ...
    }
    

    Fails with: Error: Unknown method return type: SINT

    But:

    int main(int argc, char *argv[])
    {
    ...
       qRegisterMetaType<SINT>("SINT");
       MisraInfo misra;
       engine->rootContext()->setContextProperty("misra", &misra);
    ...
    }
    

    Works!

    This is the way how Qt/QML type convertion between C++ and QML/JavaScript world works.
    If you want to define each base type as new type, you have to register it to be able to use it with QML and/or signal/slots.



  • Wow! Thanks for explaining this:

    #include <QGuiApplication>
    #include <QQmlApplicationEngine>
    #include <QQmlContext>
    
    typedef int SINT;
    
    class MisraInfo : public QObject
    {
        Q_OBJECT
    
    public:
        explicit MisraInfo(QObject * parent = Q_NULLPTR) : QObject(parent)
        {
        }
    
        Q_INVOKABLE SINT touchMe()
        {
            static SINT counter = 0;
    
            return ++counter;
        }
    };
    
    int main(int argc, char *argv[])
    {
        QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    
        QGuiApplication app(argc, argv);
    
        QQmlApplicationEngine engine;
    
        qRegisterMetaType<SINT>("SINT"); // register custom type
        MisraInfo misra;
        engine.rootContext()->setContextProperty("misra", &misra);
    
        engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
        if (engine.rootObjects().isEmpty())
            return -1;
    
        return app.exec();
    }
    
    #include "main.moc"
    

    qml:

    import QtQuick 2.9
    import QtQuick.Window 2.2
    
    Window {
        visible: true
        width: 640
        height: 480
        title: qsTr("Hello World")
    
        Component.onCompleted: {
            console.log(misra.touchMe())
            console.log(misra.touchMe())
            console.log(misra.touchMe())
            console.log(misra.touchMe())
            console.log(misra.touchMe())
        }
    }
    


  • @KroMignon
    Thank You.



  • @Phadnis your welcome


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.