Important: Please read the Qt Code of Conduct -

Dynamically adding children to a gridLayout

  • Hi all,

    I need to add children to a gridLayout dynamically. Ids and content are supplied by a C++ object (controller). Here is the QML code I'm using:

            GridLayout {
                id: gridLayout
                width: 100
                height: 100
                Layout.fillHeight: false
                columns: 3
                Layout.alignment: Qt.AlignLeft | Qt.AlignTop
                Layout.fillWidth: true
                Component.onCompleted: {
                    var imports = 'import QtQuick 2.7; import QtQuick.Controls 2.1; ';
                    var defs = controller.getInputFieldDefinitions();
                    for(var i = 0; i < defs.length; i++)
                        Qt.createQmlObject(imports + defs[i], gridLayout);

    Here are the defs coming from the controller:

    "Label { id: labelOmschrijving; text: "Omschrijving" }"
    "TextField { id: textFieldOmschrijving; text: ""; selectByMouse: true }"
    "Button { id: buttonOmschrijving; text: "x"; width: 2; onClicked: textFieldOmschrijving.clear() }"
    "Label { id: labelSleufnr; text: "Sleufnr." }"
    "TextField { id: textFieldSleufnr; text: ""; selectByMouse: true }"
    "Button { id: buttonSleufnr; text: "x"; width: 2; onClicked: textFieldSleufnr.clear() }"
    "Label { id: labelKleur; text: "Kleur" }"
    "TextField { id: textFieldKleur; text: ""; selectByMouse: true }"
    "Button { id: buttonKleur; text: "x"; width: 2; onClicked: textFieldKleur.clear() }"
    "Label { id: labelDiameter_mm; text: "Diameter (mm)" }"
    "TextField { id: textFieldDiameter_mm; text: ""; selectByMouse: true }"
    "Button { id: buttonDiameter_mm; text: "x"; width: 2; onClicked: textFieldDiameter_mm.clear() }"
    "Label { id: labelMateriaal; text: "Materiaal" }"
    "TextField { id: textFieldMateriaal; text: ""; selectByMouse: true }"
    "Button { id: buttonMateriaal; text: "x"; width: 2; onClicked: textFieldMateriaal.clear() }"
    "Label { id: labelMedium; text: "Medium" }"
    "TextField { id: textFieldMedium; text: ""; selectByMouse: true }"
    "Button { id: buttonMedium; text: "x"; width: 2; onClicked: textFieldMedium.clear() }"
    "Label { id: labelNetbeheerder; text: "Netbeheerder" }"
    "TextField { id: textFieldNetbeheerder; text: ""; selectByMouse: true }"
    "Button { id: buttonNetbeheerder; text: "x"; width: 2; onClicked: textFieldNetbeheerder.clear() }"

    The layout has 3 columns, each with a Label, TextField and Button (to clear the TextField).

    It works (the objects are created), but the layout doesn't do its job properly anymore. That is, the children take their default sizes which is too large (wide), the layout should make them smaller. If I manually add the QML for one row it works fine.

    Where does this go wrong? Hope someone can help...


  • Solved my own issue. I needed to explicitly 'import QtQuick.Layouts 1.3' with the local QML. Now it works!

  • @dimitriw The items(children) inside GridLayout(or any layout) doesn't resize when GridLayout resizes rather they re-position automatically. Hope this answers your question.

  • @Yashpal Not really I'm afraid. I'd say that the GridLayout should resize its children, that's its function, right? As I said, when I manually put in the QML code for one line (Label, TextField and Button) all works fine.

  • I think I found what the issue is. The TextField needs to get a 'Layout.fillWidth: true', then the children are properly resized within the GridLayout. But I cannot set this when I use Qt.createQmlObject, I get this error:

    Error: Qt.createQmlObject(): failed to create object:
    qrc:/inline:1:99: Non-existent attached object

    Apparently it doesn't know the parent GridLayout at that point..

  • Solved my own issue. I needed to explicitly 'import QtQuick.Layouts 1.3' with the local QML. Now it works!

  • @dimitriw Glad you were able to solve the problem and thank you for sharing the solution.