How to pass properties to a Loader created object?

Viewed 10449

I have a QML Loader which loads another qml

Loader { id: gaugeLoader }

PieMenu {
    id: pieMenu

    MenuItem {
        text: "Add Bar Gauge"
        onTriggered: gaugeLoader.source = "qrc:/Gauges/horizontalBarGauge.qml"
    }
    MenuItem {
        text: "Action 2"
        onTriggered: print("Action 2")
    }
    MenuItem {
        text: "Action 3"
        onTriggered: print("Action 3")
    }
}

How can I pass parameters to set the ID, width, height and so on of the loaded qml?

2 Answers

I would have never figured this out without @m7913d. I'm expanding on his answer (using Option 2) to help others that are trying to do something similar to me:

  • Pass delegate to GridView that displays data from an AbstractListViewModel
  • delegate SourceComponent injected by Loader

Note: I was struggling to understand the Loader was receiving the UserData returned by model::data(..).

Use Loader to pass UserData returned by model::data(.....)

GridView {
    id: trainingDataSelectGrid
    anchors.fill: parent

    cellWidth: parent.width/3
    cellHeight: parent.height/2

    model: trainingDataListModel
    delegate: Component {
        id: trainingDataDelegate
        Loader {
            sourceComponent: {
                if (index == 0) {
                    return trainingDataModel.addNewComp
                } else {
                    return trainingDataModel.dataComp
                }
            }
            // Loader binds properties to the source component
            // passed to the view delegate
            property string _name: name
            property string _author: author
            property string _author_email: author_email
            property string _created: created
            property string _updated: updated
            property int _net: net
            property int _img_width: img_width
            property int _img_height: img_height
            property int _index: index
        }
    }
    TrainingDataModel {
        id: trainingDataModel
        cardWidth: trainingDataSelectGrid.cellWidth
        cardHeight: trainingDataSelectGrid.cellHeight
    }
}

Both of my source components existed in trainingDataModel (QML: TrainingDataModel).

Before:

property Component dataComp: activeCard
property Component addNewComp: addNew
property string name
property string author
property string author_email
property string created
property string updated
property int net
property int img_width
property int img_height
property int index

property int cardWidth
property int cardHeight

property int paneWidth: cardWidth * 0.95
property int paneHeight: cardHeight * 0.95
property int materialElevate: 5
property string materialBgColor: "white"

id: cardBody

Component {
    id: addNew
    Rectangle {
        id: card
    }
}

Component {
    id: activeCard
        Rectangle{......}
    }
}

After: Move Variables to the Scope of the component that Loader will instantiate

property Component dataComp: activeCard
property Component addNewComp: addNew

property int cardWidth
property int cardHeight

property int paneWidth: cardWidth * 0.95
property int paneHeight: cardHeight * 0.95
property int materialElevate: 5
property string materialBgColor: "white"

id: cardBody

Component {
    id: addNew
}

Component {
    id: activeCard

    Rectangle {
        id: activeCardBackground
        width: cardWidth
        height: cardHeight
        color: "transparent"

        property string name: _name
        property string author: _author
        property string author_email: _author_email
        property string created: _created
        property string updated: _updated
        property int net: _net
        property int img_width: _img_width
        property int img_height: _img_height
        property int index: _index

        /// Use properties below
    }
}
  • Use temporary variables (i.e. _xxxx) to avoid naming collisions passing values from loader to delegate source component
Related