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. Finding QML Components from C++
Forum Updated to NodeBB v4.3 + New Features

Finding QML Components from C++

Scheduled Pinned Locked Moved Solved QML and Qt Quick
qmlqml contextc++
8 Posts 3 Posters 10.8k 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.
  • X Offline
    X Offline
    Xandl
    wrote on 19 Dec 2015, 14:14 last edited by Xandl
    #1

    Hello everyone,

    i am trying to find an QML Item from C++ and followed this post as well as the documentation:

    http://doc.qt.io/qt-5/qtqml-cppintegration-interactqmlfromcpp.html

    http://stackoverflow.com/questions/23177839/how-can-i-access-my-window-object-properties-from-c-while-using-qqmlapplicatio

    Instead of QQmlApplicationEngine i am using QQmlEngine.
    Since the documentation states that "Each QML component is instantiated in a QQmlContext. ... In this case, the Text item will be created in the engine's root context.", i create()'d a QQmlComponent with my QQmlEngine given as both, engine and parent in the constuctur, resulting in the created component beeing no were to be found. All of my QQmlEngine's contexts are empty. Yet the console prints that the Component completed successfully.

    main.cpp

    #include <QGuiApplication>
    #include <QQmlApplicationEngine>
    #include <QQmlEngine>
    #include <QQmlContext>
    #include <QQmlComponent>
    #include <QDebug>
    
    int main(int argc, char *argv[]) {
        QGuiApplication app(argc, argv);
        QQmlEngine* qmlEngine = new QQmlEngine(0);
    
        QQmlComponent* myComponent = new QQmlComponent(qmlEngine, qmlEngine);
        myComponent->loadUrl( QUrl( QStringLiteral("qrc:/main.qml")));
    
        QObject* myComponentObj = myComponent->create();
        if (myComponentObj == 0 || myComponent->isError()) {
            qDebug() << "Error loading main" << myComponent->errorString();
        }
    
        // The docu says new QML Compnontents are created in the QQmlEngine's root context
    
        qDebug() << "RootContext-Children: " << qmlEngine->rootContext()->children();
        // resulting in empty list = "()"
    
        qDebug() << "ContextForObjectContext-Children" << QQmlEngine::contextForObject(myComponentObj)->children();
    
        // actual task:
        QObject *qmlObject = qmlEngine->rootContext()->findChild<QObject*>("myObjectYo");
    
        if (qmlObject == 0) {
            qDebug() << "'myObjectYo' NOT FOUND."; // main problem.
        }
        else {
            qDebug() << "yay!";
        }
    
        return app.exec();
    }
    

    main.qml

    import QtQuick 2.5
    
    Item {
        objectName: "myObjectYo"
        Component.onCompleted: console.log("'" + objectName + "' created!")
    }
    

    console output

    QML debugging is enabled. Only use this in a safe environment.
    qml: 'myObjectYo' created!
    RootContext-Children:  ()
    ContextForObjectContext-Children ()
    'myObjectYo' NOT FOUND.
    

    Any ideas on this?

    1 Reply Last reply
    0
    • B Offline
      B Offline
      benlau
      Qt Champions 2016
      wrote on 9 Jan 2016, 13:41 last edited by
      #2

      You should search from qmlEngine->rootObjects().first() . Moreover, if you need to search for root object, you need to do a comparison by yourself before running findChild. findChild search child but not include the parent object.

      1 Reply Last reply
      0
      • L Offline
        L Offline
        lqsa
        wrote on 10 Jan 2016, 01:14 last edited by lqsa 1 Oct 2016, 01:16
        #3

        You must to set the parent item on a view:

        QQuickView *quickView = new QQuickView(qmlEngine, nullptr);
        quickView->setSource(QUrl(mainView));
        QQuickItem *item = qobject_cast<QQuickItem*>(myComponentObj);
        item->setParentItem(quickView->rootObject());
        
        1 Reply Last reply
        0
        • X Offline
          X Offline
          Xandl
          wrote on 12 Jan 2016, 09:36 last edited by
          #4

          @benlau said:

          You should search from qmlEngine->rootObjects().first() . Moreover, if you need to search for root object, you need to do a comparison by yourself before running findChild. findChild search child but not include the parent object.

          Yet the component is a child, so it should be poping up when im asking it's parent, the qmlEngine, for it's children, no?
          Or is the QObject* parent parameter just for fun here?

          @lqsa said:

          You must to set the parent item on a view:

          QQuickView *quickView = new QQuickView(qmlEngine, nullptr);
          quickView->setSource(QUrl(mainView));
          QQuickItem *item = qobject_cast<QQuickItem*>(myComponentObj);
          item->setParentItem(quickView->rootObject());
          

          Have you read the example code?

          1 Reply Last reply
          0
          • B Offline
            B Offline
            benlau
            Qt Champions 2016
            wrote on 12 Jan 2016, 09:48 last edited by
            #5

            @Xandl said:

            @benlau said:

            You should search from qmlEngine->rootObjects().first() . Moreover, if you need to search for root object, you need to do a comparison by yourself before running findChild. findChild search child but not include the parent object.

            Yet the component is a child, so it should be poping up when im asking it's parent, the qmlEngine, for it's children, no?
            Or is the QObject* parent parameter just for fun here?

            Don't understand which QObject* parameter you mean.

            In your example code, myObjectYo is the root object. Therefore, qmlEngine->rootObjects().first() should be equal to myObjectYo. So if you want to find any component from QQmlEngine. You should use this code

            QObject *qmlObject = 0;
            if ( qmlEngine->rootObjects().first()->objectName() == "myObjectYo") {
              qmlObject = qmlEngine->rootObjects().first();
            } else {
              qmlObject = qmlEngine->rootObjects().first()->findChild<QQobject*>("myObjectYo");
            }
            
            1 Reply Last reply
            1
            • X Offline
              X Offline
              Xandl
              wrote on 13 Jan 2016, 22:44 last edited by Xandl
              #6

              @benlau said:

              Don't understand which QObject* parameter you mean.

              QQmlComponent(QQmlEngine * engine, QObject * parent = 0)

              @benlau said:

              In your example code, myObjectYo is the root object. Therefore, qmlEngine->rootObjects().first() should be equal to myObjectYo. So if you want to find any component from QQmlEngine. You should use this code

              Yet the documentation of QQmlComponent::create states that

              QQmlComponent(QQmlEngine * engine, QObject * parent = 0)
              ...
              If context is 0 (the default), it will create the instance in the engine' s root context.
              ...

              Link QQmlComponent::create
              Edit: btw, "rootObjects()" is not a member of QQmlEngine

              1 Reply Last reply
              0
              • B Offline
                B Offline
                benlau
                Qt Champions 2016
                wrote on 14 Jan 2016, 00:44 last edited by
                #7

                I read it wrong. I just thought you are using QQmlApplicationEngine.

                Basically , context will not be the parent of created object. It define the scope of the created object like what it could access. In your case, myComponentObj should be "myObjectYo".

                1 Reply Last reply
                0
                • X Offline
                  X Offline
                  Xandl
                  wrote on 16 Jan 2016, 05:05 last edited by
                  #8

                  @benlau said:

                  I read it wrong. I just thought you are using QQmlApplicationEngine.

                  Basically , context will not be the parent of created object. It define the scope of the created object like what it could access. In your case, myComponentObj should be "myObjectYo".

                  Ok, then thank you for your affords :)
                  The goal of this experiment was to regain pointers to created objects via the QQmlEngine, because i don't have control over their creation, yet it looks like QQmlEngine alone is not capable of that.
                  So i'll close this thread and go on with QQmlApplicationEngine.
                  Thank you again.

                  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