QML ListView and ListModel index

15,028

You are doing it wrong, just use this :

import QtQuick 2.0;

Rectangle {
    width: 400;
    height: 300;

    ListView {
        id: listTest;
        clip: true;
        currentIndex: -1;
        model: ListModel {
            id: modelTest;

            ListElement { name: "Banana"; }
            ListElement { name: "Apple";  }
            ListElement { name: "Orange"; }
            ListElement { name: "Pear";   }
        }
        delegate: Item {
            id: item;
            height: 60;
            anchors {
                left: parent.left;
                right: parent.right;
            }

            property bool isCurrent : (model.index === listTest.currentIndex);
            onIsCurrentChanged: {
                if (isCurrent) {
                    input.forceActiveFocus ();
                }
                else {
                    input.focus = false;
                }
            }

            Text {
                id: label;
                font.pixelSize: 14;
                text: model.name;
                visible: !item.isCurrent;
                anchors {
                    left: parent.left;
                    right: btnUp.left;
                    margins: 20;
                    verticalCenter: parent.verticalCenter;
                }
            }
            TextInput {
                id: input;
                text: model.name;
                visible: item.isCurrent;
                onTextChanged: { modelTest.setProperty (model.index, "name", text); }
                anchors {
                    left: parent.left;
                    right: btnUp.left;
                    margins: 20;
                    verticalCenter: parent.verticalCenter;
                }

                Rectangle {
                    z: -1;
                    radius: 5;
                    antialiasing: true;
                    border {
                        width: 1;
                        color: "blue";
                    }
                    anchors {
                        fill: parent;
                        margins: -5;
                    }
                }
            }
            MouseArea {
                id: clicker;
                anchors.fill: parent;
                visible: !item.isCurrent;
                onClicked: { listTest.currentIndex = model.index; }
            }
            MouseArea {
                id: btnUp;
                width: height;
                anchors {
                    top: parent.top;
                    right: parent.right;
                    bottom: parent.verticalCenter;
                }
                onClicked: {
                    if (model.index > 0) {
                        modelTest.move (model.index, model.index -1, 1);
                    }
                }

                Text {
                    text: "V";
                    color: "gray";
                    rotation: -180;
                    anchors.centerIn: parent;
                }
            }
            MouseArea {
                id: btnDown;
                width: height;
                anchors {
                    top: parent.verticalCenter;
                    right: parent.right;
                    bottom: parent.bottom;
                }
                onClicked: {
                    if (model.index < modelTest.count -1) {
                        modelTest.move (model.index, model.index +1, 1);
                    }
                }

                Text {
                    text: "V";
                    color: "gray";
                    anchors.centerIn: parent;
                }
            }
            Rectangle {
                height: 1;
                color: "lightgray";
                anchors {
                    left: parent.left;
                    right: parent.right;
                    bottom: parent.bottom;
                }
            }
        }
        anchors.fill: parent;
    }
}
Share:
15,028
Admin
Author by

Admin

Updated on June 04, 2022

Comments

  • Admin
    Admin almost 2 years

    I have a little problem with ListModel and ListView, in particular concerning the move function of ListModel. I will show you code snippets from the DynamicList example included in the SDK with some modifications just to debug it: Code:

      Item {     
       property alias nameText:  nameTextBox.text
            id: delegateItem
            width: listView.width; height: 55
            clip: true
            Row {
                anchors.verticalCenter: parent.verticalCenter
                spacing: 10
                Column {
                    Image {
                        source: "content/pics/arrow-up.png"  
                        MouseArea {
                            anchors.fill: parent;
    
                            onClicked: {
    
                                var voice
                                var nameInModel
                                var nameInView
    
                                voice = listView.contentItem.children[1]
                                nameInModel = fruitModel.get(1).name
    
                                nameInView = voice.nameText
    
                                console.log("name before move in model at 1: "+nameInModel)
                                console.log("name before move in list at 1: "+nameInView)
    
                                 fruitModel.move(index, index-1, 1)
    
                                voice = listView.contentItem.children[1]
    
                                nameInView = voice.nameText
    
                                nameInModel = fruitModel.get(1).name
                                console.log("name after move in model at 1: "+nameInModel)
                                console.log("name after move in list at 1: "+nameInView)
    
                            }
                        }
                    }
    ....
    

    So, when the image "content/pics/arrow-up.png" is clicked, one item in the model is moved up by one position, now, in the example there are four items in order: "Apple"-"Banana"-"Cumqat"-"Durian" and this is the result of consol.log if I click "up" on the "Banana" moving that item to the first position:

    name before move in model at 1: Banana name before move in list at 1: Apple name after move in model at 1: Apple name after move in list at 1: Apple

    This is what happens if I click on Apple (that now is in the 2nd place) to moving it to the 1st position:

    name before move in model at 1: Apple name before move in list at 1: Apple name after move in model at 1: Banana name after move in list at 1: Apple

    So, first of all it is evident that the first index of ListModel is 0 while the first index of ListView is 1, then it is evident that items in the model have been moved but items in the list have not. Now, this is my problem: Imagine that "name" is the text of a TextEdit, so the the ListView delegate includes a TextEdit and it can be edited by the user. If I want to take that text I know that I can do this: Code:

    for (var i = 0; i <= myListView.count; i++){
         myItem= myListView.contentItem.children[i]
         myName = myListView.name
    

    But here is the problem, in my ListView there is also the possibility to move the items by using the move function of ListModel but if I move items and I use the previous cycle to take the "name" nothing seems to change (exactly as in the DynamicList example). On the other hand, if I take the "name" by using:

      myName= myListModel.get(i).name
    

    then, nothing seems to change when I modify the text in the TextEdit and I try to take the "name",

    So, what I have to do to obtain a ListView with TextEdit and with the possibility to move itemsof which I can record any changment?

    I hope I have been clear, Thank you very much, Giammarco