Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Retrieve object from QML files other than the main.qml



  • I am building a QtQuick app in which the main.qml file gets loaded as below:
    -----main.cpp --------
    QApplication app(argc, argv);
    QQmlApplicationEngine engine;
    ……………...
    ………..
    // Load main QML file
    engine.load(QUrl("qrc:/resources/main.qml"));
    QObject rootObject = engine.rootObjects().first();
    m_vtkFboItem = rootObject->findChild<QVTKFramebufferObjectItem
    >("vtkFboItem");
    .……..
    app.exec();

    Apart from the main.qml file I have another qml file called MyRect.qml.
    Here is the main.qml file's content:

    ApplicationWindow {
    id: root
    Rectangle {
    id: screenCanvasUI
    anchors.fill: parent

        /*MyRect{
            objectName: "rect"
        }*/
    
        VtkFboItem { //If it stays inside the main.qml file as in here it works!
           objectName: "vtkFboItem"
    

    ……………...

        }
    

    }
    }
    If the VtkFboItem item stays inside the main.qml file as shown above it works fine.
    But, if I place the VtkFboItem inside the MyRect.qml I can't locate it from the main.cpp file using the engine.rootObjects().first() method.

    Could anybody provide any guideline about how to access QML objects (that resides in QML files other than the main,qml) from C++?

    Thanks a lot.



  • @Synfony That's because when you do engine.rootObjects().first() you get your main.qml object. From main.qml you can only access your MyRect layout. You would have to access your MyRect item and from there access your VtkboItem in order for it to work.

    What you can do with this approach is access custom properties defined on the MyRect layout, so i.e. you could make an alias to your VtFboItem on MyRect and then access it with:
    QQmlProperty::read(childObject, "someProperty") where childObject is your MyRect item.



  • hi
    @Synfony said in Retrieve object from QML files other than the main.qml:

    But, if I place the VtkFboItem inside the MyRect.qml I can't locate it from the main.cpp file using the engine.rootObjects().first() method.

    you are loading "main.qml" , so engine.rootObjects().first() references your ApplicationWindow in the main.qml

    @Synfony said in Retrieve object from QML files other than the main.qml:

    Could anybody provide any guideline about how to access QML objects (that resides in QML files other than the main,qml) from C++?

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


  • Qt Champions 2018

    @Synfony said in Retrieve object from QML files other than the main.qml:

    Could anybody provide any guideline about how to access QML objects (that resides in QML files other than the main,qml) from C++?

    Don't.

    Expose data in C++ and react to it in QML.



  • Dear All,
    Many thanks for your responses. It looks like I am trying to access the item in the wrong list. I guess I should explain the issue more clearly. I have two qml files: the main.qml and the MyRect.qml; the contents of each looks as below:
    //main.qml file
    ApplicationWindow {
    id: root
    Rectangle {
    id: screenCanvasUI
    anchors.fill: parent

        MyRect{
            //objectName: "rect"
        }
    
        
    }
    

    }//end:ApplicationWindow

    //MyRect.qml file:
    Item{
    VtkFboItem {
    objectName: "vtkFboItem"
    anchors.fill: parent

        MouseArea {
    	 .............
        }
    }//end: VtkFBO
    

    }//end: Item

    Now, in order to connect the "vtkFboItem" with C++ code I am using the following code from cpp file:
    // Load main QML file
    engine.load(QUrl("qrc:/resources/main.qml"));
    // Get reference to the QVTKFramebufferObjectItem created in QML
    QObject* rootObject = engine.rootObjects()[0];
    m_vtkFboItem = rootObject->findChild<QVTKFramebufferObjectItem*>("vtkFboItem");

    QObject* rootObject = engine.rootObjects()[0];
    m_vtkFboItem = rootObject->findChild<QVTKFramebufferObjectItem*>("vtkFboItem");

    if (m_vtkFboItem)
    {
    m_vtkFboItem->setProcessingEngine(m_processingEngine);
    connect(m_vtkFboItem, &QVTKFramebufferObjectItem::rendererInitialized, this, &CanvasHandler::startApplication);
    .....................
    }
    app.exec();

    But, it is not working as shown above. If I use "MyRect.qml" in engine.load("MyRect.qml") then the applicatinWindow does not load.
    I am not quite sure how should I be able to achieve the connection (as in the code above) using custom property in MyRect.qml.

    What should be the standard approach in this case? Perhaps, a few lines of sample code would help!

    I appreciate your wise suggestions.
    Please help!



  • @Synfony said in Retrieve object from QML files other than the main.qml:

    If I use "MyRect.qml" in engine.load("MyRect.qml") then the applicatinWindow does not load.

    why would you do that ? what is your final goal ?

    Please try to explain what are you trying to do;
    are you trying to :
    instanciate a VtkFboItem Qml component in your main.qml inside a Rectangle and access it from your main.cpp ??

    Please use Forum "Code </>" tool to past your codes with correct formatting



  • ApplicationWindow {
    id: root
    Rectangle {
    id: screenCanvasUI
    anchors.fill: parent
       Drawer{
          ……..
       }
       MyRect{  }   
     
    }
    }//end:ApplicationWindow
    
    


  • @LeLev
    In the main.qml file I have navigation elements (e.g. Drawer) and other UI elements (e.g. tabs, splitter etc.) and inside the main.qml I need to display MyRect.qml (it holds the VtkFboItem).
    I also need to connect the VtkFboItem with the C++ object to display AND interact with 3D graphics.

    ApplicationWindow {
      id: root
      Rectangle {
         id: screenCanvasUI
         anchors.fill: parent
         Drawer{
          ……..
         }
          MyRect{  }   
     
        }
        Button {
                id: openFileButton
                text: "Add Model"
            …………...
        }
       FileDialog {.....}
    }//end:ApplicationWindow
    
    /MyRect.qml file:
    Item{
          VtkFboItem {
               objectName: "vtkFboItem"
              anchors.fill: parent
                MouseArea {
    	 .............
              }
           }//end: VtkFBO
          
    }//end: Item
    
    //main.cpp file
    .......
    // Load main QML file
    engine.load(QUrl("qrc:/resources/main.qml"));
    // Get reference to the QVTKFramebufferObjectItem created in QML
    QObject* rootObject = engine.rootObjects()[0];
    m_vtkFboItem = rootObject->findChild<QVTKFramebufferObjectItem*>("vtkFboItem");
    QObject* rootObject = engine.rootObjects()[0];
    m_vtkFboItem = rootObject->findChild<QVTKFramebufferObjectItem*>("vtkFboItem");
    if (m_vtkFboItem)
    {
         m_vtkFboItem->setProcessingEngine(m_processingEngine);
         connect(m_vtkFboItem,           &QVTKFramebufferObjectItem::rendererInitialized, this, &CanvasHandler::startApplication);
    .....................
    }
    app.exec();
    
    
    

    In the above scenario, how should I be able to find and connect to the vtkFboItem from the main.cpp?

    Is there any other way to achieve this apart from the objectName?
    I have attached here a screenshot of the final UI that I am trying to achieve.VTK-in-QML.PNG


Log in to reply