Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Mobile and Embedded
  4. How to get a valid object instance of a QQuickItem on C++ side
Forum Updated to NodeBB v4.3 + New Features

How to get a valid object instance of a QQuickItem on C++ side

Scheduled Pinned Locked Moved Unsolved Mobile and Embedded
9 Posts 2 Posters 4.3k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • N Offline
    N Offline
    Nelson_Piquet
    wrote on last edited by Nelson_Piquet
    #1

    Alright. I have searched a lot but haven't got a good solution yet. I am new to Qt. I have a class which is a QQuickItem like so,

    class MyQuickItemClass : public QQuickItem
    {
        Q_OBJECT
        SetInfo(SomeCppClass object)
    };
    

    I do a qmlRegisterType in my main.cpp to register it on the qml side like this,

    qmlRegisterType< MyQuickItemClass >("MyQuickItemClass", 1, 0, "MyQuickItemClass");

    All fine till here. But -> I want to set an object instance & some properties in MyQuickItemClass which some C++ logic in it as well & then pass the MyQuickItemClass object to qml. Or, get a valid instance of MyQuickItemClass from Qml. How can I get a vlid instance MyQuickItemClass object instance from QML on C++ side in main.cpp ?

    I tried doing the following learning from the link here. But this technique creates two separate objects of MyQuickItemClass. One from QML, & one from c++ side. Hence does not work for me.

    Following is how I am trying to do this after lot of searching.

    int main(int argc, char *argv[]) 
    {
      qmlRegisterType< MyQuickItemClass >("MyQuickItemClass", 1, 0, "MyQuickItemClass");
      QQmlApplicationEngine engine;
      SomeCppClass someCppClassObject;
      someCppClassObject.updateSomething();
    
      MyQuickItemClass myquickItemObject;
      myquickItemObject.SetInfo(someCppClassObject);
      engine.rootContext()->setContextProperty("myquickItemObject", &myquickItemObject);
    
      engine.load(QUrl(QStringLiteral("qrc:/qml/main.qml")));
      return app.exec();
    }
    

    But, doing the above gets the constructor of MyQuickItemClass called twice. Once from cpp side when I created an object, and once from qml side. Verified this by placing a breakpoint in the constructor of MyQuickItemClass as well. As a result, someCppClassObject that I had set is null inside MyQuickItemClass when program runs. Because qml has made the final call to MyQuickItemClass to instantiate, thusly ignoring the MyQuickItemClass object that I created in main.cpp.

    Here is my qml´ code for MyQuickItemClass`:

    import QtQuick 2.5
    import MyQuickItemClass 1.0
    
    ParentContainerItem {
      id: parentItem
      color: "black"
    
      MyQuickItemClass {
          id: myQuickItemID
          visible: true
          objectName: "myQuickItem"
    
          property bool someProperty1: false
          property bool someProperty2: true
    
          anchors.top: parent.top
          anchors.horizontalCenter: parent.horizontalCenter
      }
    
      //Other qml components
    }
    

    And this is the C++ class whose object needs to be set into MyQuickItemClass.

    SomeCppClass {
      //Pure C++ class. No Qt
    }
    

    Please note that I need to keep MyQuickItemClass derived from QQuickItem. Please suggest...

    1 Reply Last reply
    0
    • p3c0P Offline
      p3c0P Offline
      p3c0
      Moderators
      wrote on last edited by
      #2

      @Nelson_Piquet Use findChild to find that instantiated QML type from C++ using objectName and cast it to QQuickItem

      157

      N 1 Reply Last reply
      0
      • p3c0P p3c0

        @Nelson_Piquet Use findChild to find that instantiated QML type from C++ using objectName and cast it to QQuickItem

        N Offline
        N Offline
        Nelson_Piquet
        wrote on last edited by
        #3

        @p3c0 Thanks for your attention on this. Can you pls show some sample code ?

        1 Reply Last reply
        0
        • p3c0P Offline
          p3c0P Offline
          p3c0
          Moderators
          wrote on last edited by
          #4

          @Nelson_Piquet Follow this link:
          http://doc.qt.io/qt-5/qtqml-cppintegration-interactqmlfromcpp.html#accessing-loaded-qml-objects-by-object-name

          157

          N 1 Reply Last reply
          0
          • p3c0P p3c0

            @Nelson_Piquet Follow this link:
            http://doc.qt.io/qt-5/qtqml-cppintegration-interactqmlfromcpp.html#accessing-loaded-qml-objects-by-object-name

            N Offline
            N Offline
            Nelson_Piquet
            wrote on last edited by
            #5

            @p3c0 I saw the code in the link you provided.

            QObject *rect = object->findChild<QObject*>("rect");
            if (rect)
                 rect->setProperty("color", "red");
            

            Can I pass a pure C++ class object instance into setProperty ?

            1 Reply Last reply
            0
            • p3c0P Offline
              p3c0P Offline
              p3c0
              Moderators
              wrote on last edited by
              #6

              @Nelson_Piquet I guess. Maybe you can try QVariant::fromValue but first Does this solve your original question? I.e getting access of QML object from C++?

              157

              N 1 Reply Last reply
              1
              • p3c0P p3c0

                @Nelson_Piquet I guess. Maybe you can try QVariant::fromValue but first Does this solve your original question? I.e getting access of QML object from C++?

                N Offline
                N Offline
                Nelson_Piquet
                wrote on last edited by Nelson_Piquet
                #7

                @p3c0 I read & tried to understand this technique of findChild. Not sure how I can change my main.cpp to include this technique of findchild. Doesnt it require to change the way I am loading my main.qml ? Below is the full code demonstration of how I should do this with findchild. Right ?

                QQuickView view;
                view.setSource(QUrl::fromLocalFile("main.qml"));
                view.show();
                QObject *object = view.rootObject();
                QObject *rect = object->findChild<QObject*>("MyQuickItemClass");
                if (rect)
                    rect->setProperty("color", "red");
                

                But Can I set a C++ class object into SetProperty ?

                I looked at some other possibilities: Below is something I have cooked up but YET TO SOLVE THE PROBLEM !!!!

                qmlRegisterType< MyQuickItemClass >("MyQuickItemClass", 1, 0, "MyQuickItemClass");
                QQmlApplicationEngine engine;
                HelloCpp cppObjectOnqmlSide;
                qmlRegisterType<HelloCpp>("HelloCppClass", 1, 0, "HelloCppObj");
                engine.rootContext()->setContextProperty("theCppObject", &cppObjectOnqmlSide);
                engine.load(QUrl(QStringLiteral("qrc:/qml/main.qml")));
                return app.exec();
                

                Now on the QML side, below is what I am doing

                import HelloCppClass 1.0
                
                HelloCppObj {
                        id: theCppObject
                }
                
                MyQuickItemClass {
                  id: myQuickItemID
                  visible: true
                  objectName: "myQuickItem"
                
                  property bool someProperty1: false
                  property bool someProperty2: true
                
                  anchors.top: parent.top
                  anchors.horizontalCenter: parent.horizontalCenter
                
                 Component.onCompleted: {
                     print("MyQuickItemClass Component.onCompleted called")
                     theCppObject.printMessage("someMessage") //Can I pass MyQuickItemClass object into printMessage ?
                  }
                

                }

                My question is : Can I pass MyQuickItemClass object into printMessage ? How should I change printMessage to do that ? If I can, then this should solve my problem

                1 Reply Last reply
                0
                • p3c0P Offline
                  p3c0P Offline
                  p3c0
                  Moderators
                  wrote on last edited by p3c0
                  #8

                  @Nelson_Piquet Your original question as seen in the title of this post:

                  How to get a valid object instance of a QQuickItem on C++ side

                  Yes. Using findChild was the answer.

                  Now coming to your second question:

                  Can I pass MyQuickItemClass object into printMessage ? How should I change printMessage to do that ? If I can, then this should solve my problem

                  Yes. Modify your printMessage function to accept MyQuickItemClass class instance as a paramater. Then when you call the function from QML just pass this to it:

                  Component.onCompleted: {
                       print("MyQuickItemClass Component.onCompleted called")
                       theCppObject.printMessage(this) 
                  }
                  

                  Or if its from outside just pass MyQuickItemClass id i.e myQuickItemID

                  157

                  N 1 Reply Last reply
                  3
                  • p3c0P p3c0

                    @Nelson_Piquet Your original question as seen in the title of this post:

                    How to get a valid object instance of a QQuickItem on C++ side

                    Yes. Using findChild was the answer.

                    Now coming to your second question:

                    Can I pass MyQuickItemClass object into printMessage ? How should I change printMessage to do that ? If I can, then this should solve my problem

                    Yes. Modify your printMessage function to accept MyQuickItemClass class instance as a paramater. Then when you call the function from QML just pass this to it:

                    Component.onCompleted: {
                         print("MyQuickItemClass Component.onCompleted called")
                         theCppObject.printMessage(this) 
                    }
                    

                    Or if its from outside just pass MyQuickItemClass id i.e myQuickItemID

                    N Offline
                    N Offline
                    Nelson_Piquet
                    wrote on last edited by
                    #9

                    @p3c0 Sorry about swaying from the original question. Thanks a lot for all the information. That helps.

                    1 Reply Last reply
                    0

                    • Login

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • Users
                    • Groups
                    • Search
                    • Get Qt Extensions
                    • Unsolved