[SOLVED] Q_INVOKABLE vs Q_PROPERTY (QML hanging...)



  • Hi,

    I don't understand why using Q_INVOKABLE instead of Q_PROPERTY to return a QObject derivated class pointer method made my application crashing/hanging. Moreover I see this error message in my console

    Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse) Error
    

    Like the memory is double free somewhere....

    Here is how to reproduce :

    class ChildrenClass : public QObject
    {
        Q_OBJECT
    public:
        explicit SubClass(QObject *parent = 0);
        Q_INVOKABLE QString getData() {return "Hello world !";};
    }
    
    class ParentClass : public QObject
    {
        Q_OBJECT
    public:
        explicit ParentClass (QObject *parent = 0);
    
        QObject* qmlInstance(QQmlEngine *engine, QJSEngine *scriptEngine)
        {
             return new ParentClass ();        
        }
    
        Q_INVOKABLE ChildrenClass * childrenClass() {
             return &GlobalChildrenClass; // Children class is 
        };
    }
    

    In the main.cpp, I registered the types

    ChildrenClass   GlobalChildrenClass; // Static instance of a children class
    
    int main(int argc, char *argv[])
    {
          // Register ChildrenClass
        qmlRegisterType<ChildrenClass >("ChildrenClass", 1, 0, "ChildrenClass");
    
        // Create singleton for ParentClass
        qmlRegisterSingletonType<ParentClass>("ParentClass ", 1, 0, "ParentClass ", &ParentClass ::qmlInstance);
        ...
    }
    

    Now in the main.qml

    import ChildrenClass 1.0
    
    Window {
        id : mainWindow
        width :800
        height :480
        visible: true
        ...
     
        Component.onCompleted : {
            var g = ParentClass.childrenClass().getData(); // This is hanging the application
        }
    

    But If I do :

    class ParentClass : public QObject
    {
        Q_OBJECT
        Q_PROPERTY(ChildrenClass * childrenClass READ childrenClass)
    public:
        explicit ParentClass (QObject *parent = 0);
    }
    
    ...
        Component.onCompleted : {
            var g = ParentClass.childrenClass.getData(); // This is well working :) !
        }
    

    It is a bug or QML JS engine is not able to retrieved a subclass pointer and then calling a function of this pointer ? Or maybe there something wrong with my implementation ?

    Best regards,



  • I finally understand by myself why it why not working :)

    The parent class is exporting a pointer to the QML side. As it is a pointer, the QML Engine take the ownership and then once he finished using it, he free memory.

    So I have to add this to the ParentClass

    explicit ParentClass (QObject *parent = 0)
    {
          QQmlEngine::setObjectOwnership(&GlobalChildrenClass, QQmlEngine::CppOwnership);
    }
    

    So I deduce that a property do not free memory of a pointer, while a Q_INVOKABLE yes !.

    Except also that a Q_PROPERTY can be notifiable, I don't know Finally I don't know any other difference between Q_PROPERTY vs _Q_INVOKABLE.

    Hope it will help somebody else :)

    Best regards,


  • Lifetime Qt Champion

    Hi,

    Q_INVOKABLE is used to make functions accessible throughout Qt meta object system. Q_PROPERTY is much more complex and offers additional features


Log in to reply
 

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