Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Mixed QML/C++ app (solved)

    QML and Qt Quick
    2
    13
    3097
    Loading More Posts
    • 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
      LaurianeLt last edited by 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 1 Reply Last reply Reply Quote 0
      • L
        LaurianeLt @LaurianeLt last edited by

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

        JKSH 1 Reply Last reply Reply Quote 0
        • JKSH
          JKSH Moderators @LaurianeLt last edited by

          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 Reply Quote 0
          • L
            LaurianeLt @JKSH last edited by

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

            1 Reply Last reply Reply Quote 0
            • L
              LaurianeLt last edited by

              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 Reply Quote 0
              • L
                LaurianeLt last edited by

                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 ?

                JKSH 1 Reply Last reply Reply Quote 0
                • JKSH
                  JKSH Moderators @LaurianeLt last edited by

                  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 Reply Quote 1
                  • L
                    LaurianeLt @JKSH last edited by

                    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 Reply Quote 0
                    • L
                      LaurianeLt last edited by

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

                      1 Reply Last reply Reply Quote 0
                      • L
                        LaurianeLt last edited by

                        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" .

                        JKSH 1 Reply Last reply Reply Quote 0
                        • JKSH
                          JKSH Moderators @LaurianeLt last edited by

                          @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 Reply Quote 1
                          • L
                            LaurianeLt @JKSH last edited by

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

                            JKSH 1 Reply Last reply Reply Quote 0
                            • JKSH
                              JKSH Moderators @LaurianeLt last edited by

                              @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 Reply Quote 0
                              • First post
                                Last post