[SOLVED] QML: How to delete/access an object created with Qt.createQmlObject?



  • Hi everyone,

    I am working on automatic generation of user interface components from an XML file. I have an XML Model with XMLRoles and javascript functions that read the model and create objects via createObject(parent, {propertyName: propertyValue,...})".

    My UI components are generated, but I dont know how to access them. For example to destroy a specific button that was generated, or to change the buttons text/position. The components that I generate from XML file have id & caption as attributes that I use on creation of the button.

    I would like to say: find generated button with id="btn3" (id read from XML), and destroy this button.
    My buttons are generated but what do I do next with them? I have to connect them later on with C++ code on the background. How do I connect them, if I dont know how to access these generated buttons?

    What can I do??? Anyone any ideas?

    Thank you all!


  • Moderators

    Hi,

    For QML Dynamic object generation and deletion you can check "this":http://qt-project.org/doc/qt-5/qtqml-javascript-dynamicobjectcreation.html doc.

    bq. My UI components are generated, but I dont know how to access them.

    From the same doc consider the following example:
    @
    function createSpriteObjects() {
    component = Qt.createComponent("Sprite.qml");
    sprite = component.createObject(appWindow, {"x": 100, "y": 100});

    if (sprite == null) {
        // Error Handling
        console.log("Error creating object");
    }
    

    }
    @

    After creating "createObject":http://qt-project.org/doc/qt-5/qml-qtqml-component.html#createObject-method returns an object which can be used to access it's properties. In above case sprite.

    bq. I would like to say: find generated button with id=“btn3” (id read from XML)...

    AFAIK you can find the element by giving it an objectName. Then from C++ you can use findChild method to find that particular element. And example "here":http://qt-project.org/doc/qt-5/qtqml-cppintegration-interactqmlfromcpp.html#accessing-loaded-qml-objects-by-object-name.
    Or in pure QML way by using the "children":http://qt-project.org/doc/qt-5/qml-qtquick-item.html#children-prop property and then iterating over it.

    bq. My buttons are generated but what do I do next with them? I have to connect them later on with C++ code on the background. How do I connect them, if I dont know how to access these generated buttons?

    To do this you will have to initiate the connection from C++ side.
    You can find an example "here":http://qt-project.org/doc/qt-5/qtqml-cppintegration-interactqmlfromcpp.html#connecting-to-qml-signals

    I'm not sure if I have explained it to the point but feel free to ask further questions.



  • Hi p3c0,

    Thank you so much for your very informative response. I am a beginner in Qt/QML so any help is very appreciated.

    In my Javescript code I have:

    @var button = component.createObject(elementsColumn, {"nodeName": nodeName,"text": caption, "objectName": id});@

    Where elementsColumn is the parent of the button that is created in the run.

    In main.qml, I have declared a button and when I click it, it should display the text one of my generated buttons (with objectName="acquisitionButton". acquisitionButton is the ID of button that I read from the XML file). So in main.qml I have:

    @BtnPrimary{
    id: myBtn1
    text: "Text of one generated child"
    onClicked: console.log(acquisitionButton.text);}@

    Then in console I have this error:
    @"ReferenceError: acquisitionButton is not defined"
    @

    I have tried the same with buttons that I generate myself in QML code directly, and the console shows their text, but this doesnt happen with the buttons that are generated on the run via JS functions.

    Any idea where is my problem???
    Thank you very much for your response :)


  • Moderators

    How is Button with acquisitionButton as id created ? Dynamically created objects can't be given an id.
    And as mentioned earlier ,

    bq. After creating createObject [qt-project.org] returns an object which can be used to access it’s properties. In above case sprite.



  • it is not created as id, but as objectName. I am saying that the objectName should be the id of button read from XML as follows:

    @<Group caption="Controls">
    <Button caption="Start/Stop Measurement" id="acquisitionButton" />
    <Button caption="Reconstruct" id="reconstructionButton" />
    <Button caption="Rotate Camera View" id="rotateViewButton" />
    </Group>@

    I read this with a model, then generate the buttons. The id is cruicial to connect with software from other machines. It has to be there. Do you suggest another objectName or ????



  • Hi, I just realized my mistake. I am calling the element through its id, which is not possible as you stated above.

    Thanks for mentioning the objectName. It opened up a new vision.

    Just to wrap up for the others who may have similar problem, one way of accessing a "dynamically" created object is by giving it an objectName, then access it though JS as follows:

    @//accessing the first child of parent named "elementsColumn"
    elementsColumn.children[0].objectName@

    So p3c0, can I email you sometime if i encounter difficulties? Seems like you could help me from time to time in this first steps I am taking in qml/qt?


  • Moderators

    Or you can store the objects in a array to reference it later
    @
    property int count : 0
    property var arrayOfObjects : []
    var obj = comp.createObject(item, {"x": 20, "objectName": "obj"+count })
    arrayOfObjects[count] = obj
    count++
    @

    Sure you can email me. But it would be nice if you ask the questions here so that if the solutions are found it could be useful for others too.



  • Sure thats a great idea! Will keep posting here.

    Thank youuuuuu :)


Log in to reply
 

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