Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Mixed QML/C++ app (solved)
Forum Updated to NodeBB v4.3 + New Features

Mixed QML/C++ app (solved)

Scheduled Pinned Locked Moved QML and Qt Quick
13 Posts 2 Posters 3.6k Views 2 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.
  • L Offline
    L Offline
    LaurianeLt
    wrote on last edited by LaurianeLt
    #1

    Hi,
    I have created a mixed QML/C++ app, and I would like to be able to create a QML type object and add it to my main.qml as a child, from my main.cpp.

    I have created it by using :
    QQmlComponent component(&engine, "C:/....", QQmlComponent:PreferSynchronous);
    QObject *object = component.create();
    But now I would like to be able to specify that its parent should be my main.qml.

    Any idea ?

    Thanks !

    L 1 Reply Last reply
    0
    • L LaurianeLt

      Hi,
      I have created a mixed QML/C++ app, and I would like to be able to create a QML type object and add it to my main.qml as a child, from my main.cpp.

      I have created it by using :
      QQmlComponent component(&engine, "C:/....", QQmlComponent:PreferSynchronous);
      QObject *object = component.create();
      But now I would like to be able to specify that its parent should be my main.qml.

      Any idea ?

      Thanks !

      L Offline
      L Offline
      LaurianeLt
      wrote on last edited by
      #2

      I forgot to say that I also wrote :
      QQmlEngine::setObjectOwnerShip(object, QQmlEngine::CppOwnerShip);
      object -> setParent(&engine);

      JKSHJ 1 Reply Last reply
      0
      • L LaurianeLt

        I forgot to say that I also wrote :
        QQmlEngine::setObjectOwnerShip(object, QQmlEngine::CppOwnerShip);
        object -> setParent(&engine);

        JKSHJ Offline
        JKSHJ Offline
        JKSH
        Moderators
        wrote on last edited by
        #3

        Hi @LaurianeLt,

        I forgot to say that I also wrote :
        QQmlEngine::setObjectOwnerShip(object, QQmlEngine::CppOwnerShip);
        object -> setParent(&engine);

        That code sets the object parent, but you need to set the visual parent. See the differences here: http://doc.qt.io/qt-5/qtquick-visualcanvas-visualparent.html

        To set the visual parent, use QQuickItem::setParentItem(). (you need to typecast object to QQuickItem first)

        Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

        L 1 Reply Last reply
        0
        • JKSHJ JKSH

          Hi @LaurianeLt,

          I forgot to say that I also wrote :
          QQmlEngine::setObjectOwnerShip(object, QQmlEngine::CppOwnerShip);
          object -> setParent(&engine);

          That code sets the object parent, but you need to set the visual parent. See the differences here: http://doc.qt.io/qt-5/qtquick-visualcanvas-visualparent.html

          To set the visual parent, use QQuickItem::setParentItem(). (you need to typecast object to QQuickItem first)

          L Offline
          L Offline
          LaurianeLt
          wrote on last edited by
          #4

          Hi @JKSH ,
          Thank you for your answer, I will try that and let you know how it worked !

          1 Reply Last reply
          0
          • L Offline
            L Offline
            LaurianeLt
            wrote on last edited by
            #5

            I did as you said but I still have some problems, here is what I wrote :

            QQmlApplicationEngine engine;
            ...
            QQmlComponent component (&engine, "C:/Qt/.../Rectangle.qml", QQmlComponent:PreferSynchronous);
            QQuickItem * object = qobject_cast<QQuickItem*>(component.create());

            QQmlComponent component1 (&engine, "C:/Qt/.../main.qml", QQmlComponent:PreferSynchronous);
            QQuickItem * parent = qobject_cast<QQuickItem*>(component1.create());

            object->setParent(&engine);
            object->setParentItem(parent);
            engine.load(QUrl(QStringLiteral("qrc:/main.qml)));

            First I know that the way I create the "parent", when I run it, it opens two windows, the "main.qml" is launched twice. I would like to be able to define my "engine" as the parent but it's not a QQuickItem..

            And even like this, my qml object "rectangle.qml" does not appear in the window when I run it.

            1 Reply Last reply
            0
            • L Offline
              L Offline
              LaurianeLt
              wrote on last edited by
              #6

              So I tried to define the visual parent this way :

              QQuickItem root = qobject_cast<QQuickItem>(engine.rootObjects().first());
              object->setParentItem(root);

              It's running fine but once again, the rectangle.qml is not displayed...

              Any idea ?

              JKSHJ 1 Reply Last reply
              0
              • L LaurianeLt

                So I tried to define the visual parent this way :

                QQuickItem root = qobject_cast<QQuickItem>(engine.rootObjects().first());
                object->setParentItem(root);

                It's running fine but once again, the rectangle.qml is not displayed...

                Any idea ?

                JKSHJ Offline
                JKSHJ Offline
                JKSH
                Moderators
                wrote on last edited by
                #7

                Hi,

                Please add three backticks (```) before and after your code to make it render nicely.

                @LaurianeLt said:

                it opens two windows, the "main.qml" is launched twice.

                That's because you created the "main.qml" component twice:

                QQmlComponent component (&engine, "C:/Qt/.../Rectangle.qml", QQmlComponent:PreferSynchronous);
                QQuickItem * object = qobject_cast<QQuickItem*>(component.create()); // <-- First creation
                ...
                engine.load(QUrl(QStringLiteral("qrc:/main.qml))); // <-- Second creation
                

                I would like to be able to define my "engine" as the parent but it's not a QQuickItem.

                Why do you want to set "engine" as the parent?

                An item is painted "inside" its visual parent. An engine cannot be painted seen, so it cannot be a visual parent.

                And even like this, my qml object "rectangle.qml" does not appear in the window when I run it.

                I just realized that you are using QQmlEngine, which means that the root type inside main.qml is probably a Window, is that correct? If so, note that Window does not inherit Item, so it is not a QQuickItem either. Look for the QQuickItems inside the Window by calling engine.rootObjects().first()->children().

                I suggest you check the application output on the console. They provide many hints to help you solve your problems. You can print your own messages using qDebug():

                qDebug() << engine.rootObjects();
                

                Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                L 1 Reply Last reply
                1
                • JKSHJ JKSH

                  Hi,

                  Please add three backticks (```) before and after your code to make it render nicely.

                  @LaurianeLt said:

                  it opens two windows, the "main.qml" is launched twice.

                  That's because you created the "main.qml" component twice:

                  QQmlComponent component (&engine, "C:/Qt/.../Rectangle.qml", QQmlComponent:PreferSynchronous);
                  QQuickItem * object = qobject_cast<QQuickItem*>(component.create()); // <-- First creation
                  ...
                  engine.load(QUrl(QStringLiteral("qrc:/main.qml))); // <-- Second creation
                  

                  I would like to be able to define my "engine" as the parent but it's not a QQuickItem.

                  Why do you want to set "engine" as the parent?

                  An item is painted "inside" its visual parent. An engine cannot be painted seen, so it cannot be a visual parent.

                  And even like this, my qml object "rectangle.qml" does not appear in the window when I run it.

                  I just realized that you are using QQmlEngine, which means that the root type inside main.qml is probably a Window, is that correct? If so, note that Window does not inherit Item, so it is not a QQuickItem either. Look for the QQuickItems inside the Window by calling engine.rootObjects().first()->children().

                  I suggest you check the application output on the console. They provide many hints to help you solve your problems. You can print your own messages using qDebug():

                  qDebug() << engine.rootObjects();
                  
                  L Offline
                  L Offline
                  LaurianeLt
                  wrote on last edited by
                  #8

                  Hi @JKSH,

                  Thank you so much for your answer and the tip.

                  I realised I was creating it twice but I wanted to see if I was able this way to make my "main.qml" be the parent of "rectangle.qml".

                  I realize that what I said was not clear at all. I don't want to set "engine" as the parent, but my "main.qml" which is the qml file I load with the engine.

                  I am using QQmlEngine indeed so my main.cpp in its simplest form is this :

                  int main( int argc, char *argv[])
                  {
                  QApplication app(argc, argv);
                  QQmlApplicationEngine engine;
                  engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
                  return app.exec();
                  }
                  
                  

                  So what I want to be able to do is to create and declare an object "rectangle.qml" a child of "main.qml" from my "main.cpp".

                  I hope I am making more sense now, I will try to figure more out by looking at the children of engine.rootObjects().first().

                  Thanks again!

                  1 Reply Last reply
                  0
                  • L Offline
                    L Offline
                    LaurianeLt
                    wrote on last edited by
                    #9

                    @JKSH I forgot : the root type inside main.qml is an ApplicationWindow.

                    1 Reply Last reply
                    0
                    • L Offline
                      L Offline
                      LaurianeLt
                      wrote on last edited by
                      #10

                      I tried this :

                      qDebug << engine.rootObjects().first()->children();
                      

                      And I get something like this, with the list of the children :
                      (QQuickLoader(0x26c5ff98, QQuickItem(0x26c5fcf8), ... )

                      So I tried to get the second one, which is a QQuickItem like that :

                      QQuickItem parent = qobject_cast<QQuickItem*>(engine.rootObjects().first()->children().at(2));
                      

                      But I get a error message saying that "QQuickItem::QQuickItem(const QQuickItem&)' is private" .

                      JKSHJ 1 Reply Last reply
                      0
                      • L LaurianeLt

                        I tried this :

                        qDebug << engine.rootObjects().first()->children();
                        

                        And I get something like this, with the list of the children :
                        (QQuickLoader(0x26c5ff98, QQuickItem(0x26c5fcf8), ... )

                        So I tried to get the second one, which is a QQuickItem like that :

                        QQuickItem parent = qobject_cast<QQuickItem*>(engine.rootObjects().first()->children().at(2));
                        

                        But I get a error message saying that "QQuickItem::QQuickItem(const QQuickItem&)' is private" .

                        JKSHJ Offline
                        JKSHJ Offline
                        JKSH
                        Moderators
                        wrote on last edited by
                        #11

                        @LaurianeLt said:

                        @JKSH I forgot : the root type inside main.qml is an ApplicationWindow.

                        Yep, that inherits Window. It's not a QQuickItem.

                        QQuickItem parent = qobject_cast<QQuickItem*>(engine.rootObjects().first()->children().at(2));
                        

                        But I get a error message saying that "QQuickItem::QQuickItem(const QQuickItem&)' is private" .

                        You got that error message because the type of parent needs to be QQuickItem*, not QQuickItem.

                        Also note that counting starts from 0, so if you want the second item you should call .at(1).

                        Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                        L 1 Reply Last reply
                        1
                        • JKSHJ JKSH

                          @LaurianeLt said:

                          @JKSH I forgot : the root type inside main.qml is an ApplicationWindow.

                          Yep, that inherits Window. It's not a QQuickItem.

                          QQuickItem parent = qobject_cast<QQuickItem*>(engine.rootObjects().first()->children().at(2));
                          

                          But I get a error message saying that "QQuickItem::QQuickItem(const QQuickItem&)' is private" .

                          You got that error message because the type of parent needs to be QQuickItem*, not QQuickItem.

                          Also note that counting starts from 0, so if you want the second item you should call .at(1).

                          L Offline
                          L Offline
                          LaurianeLt
                          wrote on last edited by
                          #12

                          @JKSH Thank you so much, this is finally working !

                          JKSHJ 1 Reply Last reply
                          0
                          • L LaurianeLt

                            @JKSH Thank you so much, this is finally working !

                            JKSHJ Offline
                            JKSHJ Offline
                            JKSH
                            Moderators
                            wrote on last edited by
                            #13

                            @LaurianeLt You're welcome :) Happy coding!

                            Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                            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