[solved] QML dynamic object creation in C++



  • Hi, I'm just out on QML and am looking for some assistance in the following...

    I'm trying to dynamically create a QML object from C++ and do this without using any of the QGraphics* classes. As QGraphicsView is the current backend and will be removed I wanted to stick to using QDeclarative* classes only.

    Dynamic object creation from QML works using...
    @
    myDialog = Qt.createComponent("BaseDialog.qml").createObject(baseObj);
    @

    Dynamic object creation from C++ using QGraphicsView works using...
    @
    QDeclarativeEngine* engine = m_view.engine();
    QDeclarativeContext* context = engine->rootContext();
    QObject* rootObj = context->findChild<QObject*>("baseObj");
    QDeclarativeItem rootitem = qobject_cast<QDeclarativeItem>(rootObj);

    QDeclarativeComponent component(engine, QUrl::fromLocalFile&#40;"qml/NativeInteg/BaseDialog.qml"&#41;&#41;;
    QObject *myObject = component.create();
    QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(myObject);
    
    item->setParentItem(rootitem);
    m_view.scene()->addItem(item);
    

    @

    But using pure QDeclarative* classes I can't seem to achieve it, so far I have...
    @
    QDeclarativeContext* context = m_view.engine()->rootContext();
    QDeclarativeComponent* component = new QDeclarativeComponent(m_view.engine(), QUrl::fromLocalFile("qml/NativeInteg/BaseDialog.qml"), m_view.engine());
    QDeclarativeItem* myDialog = qobject_cast<QDeclarativeItem*>(component->create());

    QObject* child = context->findChild<QObject*>("baseObj");
    QDeclarativeItem *rootitem = qobject_cast<QDeclarativeItem*>(child);
    myDialog->setParentItem(rootitem);
    

    @

    The component.onCompleted gets fired but nothing is displayed.

    Any ideas on what I need to do next?

    Thanks in advanced.

    Omer



  • what is "baseObj", is it the objectName of your root qml component??



  • Yeah, sorry about the naming, still in prototyping phase. 'baseObj' is the name of the root element that I have loaded by my main.qml. It is intended to be the parent of the object that I trying to dynamically create.



  • then the below code seems to work
    @int main(int argc, char *argv[])
    {
    QApplication app(argc, argv);

    QDeclarativeView m_view;// =  new QDeclarativeView();
    m_view.setSource(QUrl::fromLocalFile&#40;"qml/Example/main.qml"&#41;);
    
    QDeclarativeComponent* component = new QDeclarativeComponent(m_view.engine(), QUrl::fromLocalFile&#40;"qml/Example/QML1.qml"&#41;);
    QDeclarativeItem* myDialog = qobject_cast<QDeclarativeItem*>(component->create());
    
    myDialog->setParentItem(qobject_cast<QDeclarativeItem*>(m_view.rootObject()));
    m_view.showFullScreen();
    
    return app.exec();
    

    }
    @



  • Ok cool, that works. The only thing is rootObject() in line 11 returns a QGraphicsObject so presumably this method will be removed/changed when the backend is migrated from QGraphicsView to Scene Graph?



  • so, I guess so and mark the thread as solved by appending (Solved) to the title of the thread.



  • hello,

    I have an application, in which i am using the same approach.
    now if i want to access the properties of baseObj, which meant to be parent of my dynamically created object, what should i do.

    Here is example of my code..

    main.qml
    import FirstButtonClick 1.0
    Rectangle{
    property string myString : "My String"
    Text{
    text : "main file"
    }
    MouseArea{
    onClicked:{
    buttonClick.openPage("qrc:qml/FirstButton.qml")
    }
    }

       FirstButtonClick{
              id : buttonClick
       }
    

    }

    FirstButton.qml
    Rectangle{
    Text{
    text : "FirstButton Page"
    }

        Component.onCompleted{
                    console.log("main.qml property : " + myString // main.qml property)
         }
    

    }

    main.cpp
    #include "FirstButtonClick.h"
    #include "main.h"

    int main(int argc, char *argv[])
    {
    qmlRegisterType<>("FirstButtonClick", 1, 0, "FirstButtonClick");

        QApplication app(argc, argv);     
        m_view =  new QDeclarativeView;
        m_view.setSource(QUrl("qrc:qml/main.qml"));
        m_view.showFullScreen();     
        return app.exec();
    

    }

    main.h
    QDeclarativeView* m_view;

    FirstButtonClick.h
    extern QDeclarativeView* m_view;
    class FirstButtonClick : public OQbject
    {
    Q_OBJECT;
    public :
    Q_INVOKABLE QObject* openPage(QString fileName);
    }

    FirstButtonClick.cpp
    #include "FirstButtonClick.h"

    QObject* FirstButtonClick :: openPage(QString fileName)
    {
    QDeclarativeContext* context = m_view->engine()->rootContext();
    QDeclarativeComponent* component = new QDeclarativeComponent(m_view->engine(), QUrl(fileName), m_view->engine());

         QObject * object = component->create();
         QDeclarativeItem* myDialog = qobject_cast<QDeclarativeItem*>(object); 
    
          QDeclarativeItem *rootitem = qobject_cast<QDeclarativeItem*>(m_view->rootObject());
          myDialog->setParentItem(rootitem);
    
          return object;
    

    }

    the problem with the above code is FirstButton.qml page is loaded but when it tries to access the property of main.qml ie. myString it cant access it.

    suggest me me a way to use it properly


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.