[SOLVED] Problem using QML object in C++ method !



  • Hi everybody!

    I need your help with something I thought trivial but that is driving me nuts

    I have got a QList list of C++ ClassX objects that are instantiated in my main C++ file.
    The ClassX is registered with the QML engine an I can access the list and its item just fine in QML.

    Now here comes the problem:
    I've a C++ method defined as invokable that takes a pointer to a ClassX object.
    When I call the method from QML, passing one ClassX object from the list (which is perfectly ok in QML, I can access its attributes) but the argument on the C++ side is NULL.

    Any ideas?
    thanks in advance!
    best regards
    Manfred


  • Moderators

    @Manfred How do you pass the ClassX object from QML side ? Have you instantiated it ?



  • @p3c0 Hi thanks for your reply!
    Yes, I instantiate the ClassX object on the C++ side and add it to a QList which is created in C++ as well
    QList<ClassX*> m_XList; // data model exposed to qml

    the list is then exported via a property like this:
    Q_PROPERTY(QQmlListProperty<ClassX> xList READ getXList NOTIFY xListChanged)

    Using a qml ListView I can access the C++ model just fine but when I call my C++ method from the same QML file, passing one item of that ListView, the pointer argument on the C++ side is null!
    here is the C++ method declaration:
    Q_INVOKABLE void doSomething( ClassX *x);

    BTW is there a way to mark text as source on this forum?
    thanks in advance!
    cheers
    Manfred


  • Moderators

    @Manfred As I said earlier you will need to instantiate it from QML side or somehow have access to that particular object. From the docs:

    If a C++ method has a parameter with a QObject* type, the parameter value can be passed from QML using an object id or a JavaScript var value that references the object.

    So from QML side you can either do something like this:

    import ClassX 1.0 //assuming registered already
    ClassX { //instantiate
      id: classx
    }
    
    doSomething(classx) //access using id
    

    Or since you have ListView get that particular instance may be by creating a new Q_INVOKABLE method which will return the required instance and upon return hold it in a var on QML side and pass it to the above function.

    BTW is there a way to mark text as source on this forum?

    Do you mean highlighting source code ?



  • @p3c0 Hi and thanks again for your reply!
    Unfortunately I cannot instantiate the object in QML as it is part of the data model which is instantiated and managed by C++.
    Well I think I'll change my Q_Invokable so that it takes an attribute of the object such as a string and then search it in C++ inside the list.

    But I still do not understand why the pointer of the object gets null on C++ although it is valid on the QML side.

    Concerning the source code, yes I meant highlight as you did it for the source examples in your reply.
    How did you do that?

    Thanks in advance and have a nice day!
    cheers
    Manfred


  • Moderators

    @Manfred

    But I still do not understand why the pointer of the object gets null on C++ although it is valid on the QML side.

    How did you pass it from QML ? Can you post the relevant code ?
    Also did you try the second method that I mentioned earlier.

    Concerning the source code, yes I meant highlight as you did it for the source examples in your reply.
    How did you do that?

    Surround code with ``` (3 backticks) for blocks and ` (single) for one line. It is also posted at the bottom of this post.



  • @p3c0 hI

    thank you for your reply, sorry I didn't see the markdown stuff.. 8-)

    Here is a much simplified version of my code. Please bear in mind that the object instance which is created on the C++ side is correctly exported to QML and that I can perfectly access any attributes of this same instance from QML.
    But when I pass this object back to the C++ method, the pointer to it is NULL from inside the method.

    I hope I'm clear enough ;-)

    -------------------- C++ HEADER ------------------------
    class App : public QObject
    {
        Q_OBJECT
        Q_PROPERTY( SomeClass* classInstance READ get_classInstance NOTIFY classInstanceChanged)
    public:
        Q_INVOKABLE void doSomething( SomeClass *classInstance );
    	
        explicit App(QObject *parent = 0);
        virtual ~App();
        SomeClass *get_classInstance();
        QQmlListProperty<SomeClass> getSomeClassList();
    protected:
        QList<SomeClass*> m_SomeClassList; // data model exposed to qml
        SomeClass* m_classInstance;
    
    signals:
        void classInstanceChanged();
    
    public slots:
    };
    -------------------- QML  ------------------------
    import QtQuick 2.4
    import com.mylibrary 1.0
    
    Rectangle {
    
        property SomeClass classInstance: null
    
        Component.onCompleted: {
            classInstance = theApp.classInstance
        }
    
        MouseArea {
            anchors.fill: parent
            onClicked: {
                theApp.doSomething( classInstance );            
            }
        }
    }
    


  • Hi again,
    really no ideas what's going on?


  • Moderators

    @Manfred Sorry for late reply. To make use of pointers in Q_PROPERTY you have to register it too I suppose. Check this post.



  • @p3c0 Hi thanks for your reply!

    I read trough that post and double checked my code and I had everything ok.
    While playing around, trying this and that it suddenly started working!
    I think I had a problem where the object on the qml side was not yet initialized when calling the C++ method.
    I now make sure this is the case in Component.onCompleted and all is fine!

    Thanks again for all your input
    have a nice day
    Manfred


Log in to reply
 

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