2

I am facing issue loading dynamic delegates with dynamic models using the Loaders. I am able to see the delegate of the corresponding model, but data in that delegate is not displaying. When clicking on the button, getting the error as " ReferenceError: ":name is not defined" I posted the complete example in below. Could any one suggest if I am missing any thing.

import QtQuick 2.3
import QtQuick.Window 2.2

Window {
    id: mainWindow

    property int value: 0
    property variant m_Model: modelData

    visible: true
    height: 600
    width: 700


    Row{
        id: mainButtons
        spacing: 5
        anchors.top: parent.top
        anchors.left: parent.left
        anchors.margins: 6


        Rectangle{
            id: b1
            height: 50
            width: 90
            border.width: 1
            radius: 3
            color: "skyblue"
            Text{
                anchors.centerIn: parent
                text: "Button1"
            }
            MouseArea{
                anchors.fill: parent
                hoverEnabled: true
                onClicked:{
                    listView.model=button1Model
                    value=1
                }
            }
        }
        Rectangle{
            id: b2
            height: 50
            width: 90
            border.width: 1
            radius: 3
            color: "skyblue"
            Text{
                anchors.centerIn: parent
                text: "Button2"
            }
            MouseArea{
                anchors.fill: parent
                hoverEnabled: true

                onClicked: {
                    listView.model=button2Model
                    //listView.delegate=b2Delegate
                    //loader.sourceComponent=b2Delegate
                    value=2
                }
            }
        }
        Rectangle{
            id: b3
            height: 50
            width: 90
            border.width: 1
            radius: 3
            color: "skyblue"
            Text{
                anchors.centerIn: parent
                text: "Button3"
            }
            MouseArea{
                anchors.fill: parent
                hoverEnabled: true

                onClicked: {
                    listView.model=button3Model
                    value = 3
                }
            }
        }
    }

    ListView{
        id: listView

        anchors.top: mainButtons.bottom
        anchors.left:parent.left
        anchors.margins: 3

        height: 500
        width: 600

        model: modelData

        delegate: Component{
            id: loader
            Loader{
                id: loader

                sourceComponent: {
                    switch(value)
                    {
                    case 1: {
                        return b1Delegate
                    }
                    case 2:{
                        return b2Delegate
                    }
                    case 3:{
                        return b3Delegate
                    }
                    default:
                        return listDelegate

                    }

                }
            }
        }
    }

    Component{
        id: listDelegate
        Row{

            spacing: 5
            Rectangle{
                width: 100
                height: 50
                border.width: 1
                Text{
                    anchors.centerIn: parent
                    text: name
                }
            }

            Rectangle{
                width: 100
                height: 50
                radius: 50
                border.width: 1
                Text{
                    anchors.centerIn: parent
                    text: number
                }
            }
        }

    }


    ListModel{
        id: modelData

        ListElement{
            name: "abc"
            number: "1"
        }
        ListElement{
            name: "def"
            number: "2"
        }
        ListElement{
            name: "ghi"
            number: "3"
        }
        ListElement{
            name: "jkl"
            number: "4"
        }
    }

    Component{
        id: b1Delegate

        Row{
            spacing: 5
            anchors.margins: 5

            Rectangle{
                height: 50
                width: 100
                border.width: 1
                Text{
                    anchors.centerIn: parent
                    text: SerialNO
                }

            }
            Rectangle{
                height: 50
                width: 100
                border.width: 1
                Text{
                    anchors.centerIn: parent
                    text: Name
                }

            }
            Rectangle{
                height: 50
                width: 100
                border.width: 1
                Text{
                    anchors.centerIn: parent
                    text: Marks
                }

            }
        }
    }

    ListModel{
        id: button1Model
        ListElement{
            SerialNO: "1"
            Name: "Mathametics"
            Marks: "100"
        }
        ListElement{
            SerialNO: "2"
            Name: "Science"
            Marks: "75"
        }
        ListElement{
            SerialNO: "3"
            Name: "Social"
            Marks: "80"
        }
        ListElement{
            SerialNO: "4"
            Name: "Hindi"
            Marks: "80"
        }
        ListElement{
            SerialNO: "5"
            Name: "English"
            Marks: "75"
        }

    }

    ListModel{
        id: button2Model
        ListElement{
            Name: "ABC"
        }
        ListElement{
            Name: "XYZ"
        }
        ListElement{
            Name: "PQR"
        }
        ListElement{
            Name: "IJK"
        }
    }
    ListModel{
        id: button3Model
        ListElement{
            University: "AAAAAA"
            Address: "111111"
        }
        ListElement{
            University: "BBBBBB"
            Address: "111111"
        }
        ListElement{
            University: "CCCCCC"
            Address: "111111"
        }
        ListElement{
            University: "DDDDDD"
            Address: "111111"
        }
    }

    Component
    {
        id: b2Delegate
        Row{
            spacing: 5
            anchors.margins: 5
            Rectangle{
                height: 50
                width: 100
                border.width: 1
                Text{
                    anchors.centerIn: parent
                    text: Name
                }

            }
        }
    }

    Component
    {
        id: b3Delegate
        Row{
            spacing: 5
            anchors.margins: 5

            Rectangle{
                height: 50
                width: 100
                border.width: 1
                Text{
                    anchors.centerIn: parent
                    text: University
                }

            }
            Rectangle{
                height: 50
                width: 100
                border.width: 1
                Text{
                    anchors.centerIn: parent
                    text: Address
                }

            }
        }
    }
}
Phiter
  • 14,570
  • 14
  • 50
  • 84
  • Hi Mitch, Yes I am getting the same error. How to resolve this error. because I am able to see the delegate component. – user1540436 May 13 '16 at 08:07
  • My complete model and delegate in single qml file only. I don't have much in C++. Please find the C++ code in below. #include #include int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); QQmlApplicationEngine engine; engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); return app.exec(); } – user1540436 May 13 '16 at 10:02
  • My bad. I've deleted my comments. – Mitch May 13 '16 at 11:43

2 Answers2

1

I think that using a Loader while setting a delegate is not a good idea. Try changing this:

delegate: Component{
    id: loader
    Loader{
        id: loader

        sourceComponent: {
            switch(value)
            {
            case 1: {
                return b1Delegate
            }
            case 2:{
                return b2Delegate
            }
            case 3:{
                return b3Delegate
            }
            default:
                return listDelegate

            }

        }
    }
}

To this:

delegate: {
    switch(value)
    {
    case 1: {
        return b1Delegate
    }
    case 2:{
        return b2Delegate
    }
    case 3:{
        return b3Delegate
    }
    default:
        return listDelegate
    }
}

If this does not help you please edit your answer and attach complete example code. The example you provided contains errors and I do not know which of them happen because of too short example, and which are in fact errors.

Filip Hazubski
  • 1,668
  • 1
  • 17
  • 33
  • 1
    @Hazubski: I posted the complete example code in above. My scenario in the above example isI have a list view with default model and delegate, when I clicking on button (button 1/button 2/button 3), then it has different model and delegate, depends upon the button model and delegate need to select correspondingly. If i tried to assign manually as onClicked: { – user1540436 May 13 '16 at 07:58
  • If i tried to assign manually as onClicked: {listView.model=button1Model loader.sourceComponent=b1Delegate } I am getting a RefereError of previous buttons qrc:/main.qml:200: ReferenceError: Name is not defined qrc:/main.qml:210: ReferenceError: Marks is not defined – user1540436 May 13 '16 at 08:08
0

The data from the model needs to be made visible to the delegate's scope. You can do that in a similar way as Qt Quick Controls does it:

delegate: Loader {
    property string nameData: name
    property int numberData: number

    sourceComponent: {
        switch (value) {
        case 1:
            return b1Delegate
        case 2:
            return b2Delegate
        case 3:
            return b3Delegate
        default:
            return listDelegate
        }
    }
}

Then, listDelegate would become:

Component {
    id: listDelegate
    Row {
        spacing: 5

        Rectangle {
            width: 100
            height: 50
            border.width: 1
            Text {
                anchors.centerIn: parent
                text: nameData
            }
        }

        Rectangle {
            width: 100
            height: 50
            radius: 50
            border.width: 1
            Text {
                anchors.centerIn: parent
                text: numberData
            }
        }
    }
}

Here's the correct code (I simplified some of it):

import QtQuick 2.3
import QtQuick.Window 2.2

Window {
    id: mainWindow

    property int value: 0
    property variant m_Model: modelData

    visible: true
    height: 600
    width: 700

    Row {
        id: mainButtons
        spacing: 5
        anchors.top: parent.top
        anchors.left: parent.left
        anchors.margins: 6

        Rectangle {
            id: b1
            height: 50
            width: 90
            border.width: 1
            radius: 3
            color: "skyblue"
            Text {
                anchors.centerIn: parent
                text: "Button1"
            }
            MouseArea {
                anchors.fill: parent
                hoverEnabled: true
                onClicked: {
                    listView.model = button1Model
                    value = 1
                }
            }
        }
        Rectangle {
            id: b2
            height: 50
            width: 90
            border.width: 1
            radius: 3
            color: "skyblue"
            Text {
                anchors.centerIn: parent
                text: "Button2"
            }
            MouseArea {
                anchors.fill: parent
                hoverEnabled: true

                onClicked: {
                    listView.model = button2Model
                    //listView.delegate=b2Delegate
                    //loader.sourceComponent=b2Delegate
                    value = 2
                }
            }
        }
        Rectangle {
            id: b3
            height: 50
            width: 90
            border.width: 1
            radius: 3
            color: "skyblue"
            Text {
                anchors.centerIn: parent
                text: "Button3"
            }
            MouseArea {
                anchors.fill: parent
                hoverEnabled: true

                onClicked: {
                    listView.model = button3Model
                    value = 3
                }
            }
        }
    }

    ListView {
        id: listView

        anchors.top: mainButtons.bottom
        anchors.left: parent.left
        anchors.margins: 3

        height: 500
        width: 600

        model: modelData

        delegate: Loader {
            property string nameData: name
            property int numberData: number

            sourceComponent: {
                switch (value) {
                case 1:
                    return b1Delegate
                case 2:
                    return b2Delegate
                case 3:
                    return b3Delegate
                default:
                    return listDelegate
                }
            }
        }
    }

    Component {
        id: listDelegate
        Row {
            spacing: 5

            Rectangle {
                width: 100
                height: 50
                border.width: 1
                Text {
                    anchors.centerIn: parent
                    text: nameData
                }
            }

            Rectangle {
                width: 100
                height: 50
                radius: 50
                border.width: 1
                Text {
                    anchors.centerIn: parent
                    text: numberData
                }
            }
        }
    }

    ListModel {
        id: modelData

        ListElement {
            name: "abc"
            number: "1"
        }
        ListElement {
            name: "def"
            number: "2"
        }
        ListElement {
            name: "ghi"
            number: "3"
        }
        ListElement {
            name: "jkl"
            number: "4"
        }
    }

    Component {
        id: b1Delegate

        Row {
            spacing: 5
            anchors.margins: 5

            Rectangle {
                height: 50
                width: 100
                border.width: 1
                Text {
                    anchors.centerIn: parent
                    text: SerialNO
                }
            }
            Rectangle {
                height: 50
                width: 100
                border.width: 1
                Text {
                    anchors.centerIn: parent
                    text: Name
                }
            }
            Rectangle {
                height: 50
                width: 100
                border.width: 1
                Text {
                    anchors.centerIn: parent
                    text: Marks
                }
            }
        }
    }

    ListModel {
        id: button1Model
        ListElement {
            SerialNO: "1"
            Name: "Mathametics"
            Marks: "100"
        }
        ListElement {
            SerialNO: "2"
            Name: "Science"
            Marks: "75"
        }
        ListElement {
            SerialNO: "3"
            Name: "Social"
            Marks: "80"
        }
        ListElement {
            SerialNO: "4"
            Name: "Hindi"
            Marks: "80"
        }
        ListElement {
            SerialNO: "5"
            Name: "English"
            Marks: "75"
        }
    }

    ListModel {
        id: button2Model
        ListElement {
            Name: "ABC"
        }
        ListElement {
            Name: "XYZ"
        }
        ListElement {
            Name: "PQR"
        }
        ListElement {
            Name: "IJK"
        }
    }
    ListModel {
        id: button3Model
        ListElement {
            University: "AAAAAA"
            Address: "111111"
        }
        ListElement {
            University: "BBBBBB"
            Address: "111111"
        }
        ListElement {
            University: "CCCCCC"
            Address: "111111"
        }
        ListElement {
            University: "DDDDDD"
            Address: "111111"
        }
    }

    Component {
        id: b2Delegate
        Row {
            spacing: 5
            anchors.margins: 5
            Rectangle {
                height: 50
                width: 100
                border.width: 1
                Text {
                    anchors.centerIn: parent
                    text: Name
                }
            }
        }
    }

    Component {
        id: b3Delegate
        Row {
            spacing: 5
            anchors.margins: 5

            Rectangle {
                height: 50
                width: 100
                border.width: 1
                Text {
                    anchors.centerIn: parent
                    text: University
                }
            }
            Rectangle {
                height: 50
                width: 100
                border.width: 1
                Text {
                    anchors.centerIn: parent
                    text: Address
                }
            }
        }
    }
}
Mitch
  • 23,716
  • 9
  • 83
  • 122
  • Thank you for the help , Can you please suggest if i have to use the model instead of assigning all the variables separately how can i do it. – user1540436 May 13 '16 at 14:03
  • Thank you for the help , Can you please suggest if i have to use the model instead of assigning all the variables separately how can i do it. i mean to say inside the loader, my requirement is like i will be using only some variables depending on the delegate type, now since i am declaring all the variables in loader again i am getting the same issue as earlier, but for less variables. please suggest how we can directly assign a model inside the loader depending on the delegate type. – user1540436 May 13 '16 at 14:08
  • Er, huh? I don't understand what you're trying to do. Also, you shouldn't be getting any errors with the code in this answer. – Mitch May 13 '16 at 14:09
  • I am getting the reference error as previous, but for the variables which are not available in that model. I mean suppose I am refering to button1Model and inside the loader I have defined all the variables of all the modeles, then those model variable are showing as reference error. – user1540436 May 13 '16 at 14:25
  • `code` Eg: Loader{ id: loader property variant namedata: name property variant numberdata: number property variant serialnodata: SerialNo property variant marksdata: Marks property variant subjdata: Name property variant universitydata: University property variant addressdata: Address } Now for default delegate, it is showing reference error for "SerialNO, Marks, Name, Univerisity and Address", if we click on button1 it is showing error for "name, number, university, Address" and so on. – user1540436 May 13 '16 at 14:25
  • Now my question is how we can load the model also dynamically, so that it should not refer to the other data members in other models? – user1540436 May 13 '16 at 14:27
  • Can you please paste your updated code using pastebin or something, as a link here in the comments? – Mitch May 13 '16 at 14:37
  • Hi, I have past the code in above and http://paste.ofcode.org/LfNX6A3Km9PxQDHbkVmVjF – user1540436 May 13 '16 at 18:37
  • I'm still not really sure what you're trying to do. It looks like you're trying to use several different models, each with different roles, with a single `ListView`. That doesn't strike me as a good idea. Perhaps if you update your question with an illustration of what you want to achieve with the UI? – Mitch May 13 '16 at 18:50
  • Yes my scenario is, I have multiple models and multiple delegates. I need to select the model and correspondingly need to load the delegates. I need to implement a similar kind of scenior like this. So, could you please let me know how to acheive this. – user1540436 May 13 '16 at 19:06
  • what I am trying to do is, I have a some default model and delegate during loading of the qml. I have three buttons where model of these three cases is different(different roles) correspondly i have a three delegates. Now depending on my selection of the button, model will get select and need to load the corresponding delegate to display the data. – user1540436 May 13 '16 at 19:11
  • That's not really how views work. You usually have one model per view. You might have different delegates depending on the content of a particular model item, but never several models per view. – Mitch May 13 '16 at 19:30
  • Like I said, it depends on the end result you're after. For me to understand that, I'd need some kind of illustration of what you'd like to be displayed to the user. – Mitch May 14 '16 at 13:17