在QML LISTMODEL中获取给定索引的值

时间:2017-05-15 08:49:28

标签: javascript qt qml

我有一个QML ListModel,如下所示:

ListModel {
id: myListModel
ListElement {myId: "1", myValue = "12"}
ListElement {myId: "2", myValue = "0"}
...
ListElement {myId: "21", myValue = "123"}
}

然后我有一些简单的QML标签如下:

Label {
id: myLabel1
property int labelInt: 1
text: myListModel.get().myValue; //Here is my problem!
}

Label {
id: myLabel2
property int labelInt: 22
text: myListModel.get().myValue; //Here is my problem!
}

我的问题是在myListMode.get()。myValue中填充括号。 事实上我需要一个条件: 如果myListModel有一些myId等于我当前的labelInt, 然后返回相应的myId,否则留空空格:

我尝试过:

myListModel.get(myListModel.get(myId = labelInt).myId).myValue;

但我不确定这是正确的方法。

你能帮帮我吗? 谢谢

2 个答案:

答案 0 :(得分:0)

您需要遍历模型才能找到元素。

示例:

import QtQuick 2.2
import QtQuick.Window 2.2
import QtQuick.Controls 1.4

ApplicationWindow {

    function findElement(myModel, myId) {
        for(var i = 0; i < myModel.count; i++) {
            var element = myModel.get(i);

            if(myId == element.myId) {
                console.log("Found element: ", i);
                return element.myId;
            }
        }
        return "";
    }


    id: window
    visible: true

    TableView {
        y: 70
        width: 500

        TableViewColumn {
            role: "myId"
            title: "myId"
            width: 100
        }

        TableViewColumn {
            role: "myValue"
            title: "myValue"
            width: 100
        }

        model: myListModel

        ListModel {
            id: myListModel
            ListElement
            {
                myId: "1"
                myValue: "12"
            }
            ListElement
            {
                myId: "2"
                myValue: "0"
            }
            ListElement
            {
                myId: "21"
                myValue: "123"
            }
        }
    }

    Label
    {
        id: myLabel1
        property int labelInt: 1
        x: 0
        text: findElement(myListModel, labelInt);
    }

    Label
    {
        id: myLabel2
        property int labelInt: 22
        x: 100
        text: findElement(myListModel, labelInt);
    }
}

答案 1 :(得分:0)

如果您想要速度,则应将条目映射到myId

在QML中,您可以将InstantitatorJSObject组合使用。

property var tracker: ({})

Instantiator {
    model: tm
    delegate: QtObject {
        id: instDummy
        property QtObject modelData: model
        property string __oldID
        property string myID: model.myID

        onMyIDChanged: {
            if (myID && __oldID !== myID) {
                delete tracker[__oldID]
                __oldID = myID
                tracker[__oldID] = instDummy
                console.log('changed', Object.keys(tracker))
            }
        }

        Component.onCompleted: {
            __oldID = myID
        }
        Component.onDestruction: {
            console.log(__oldID, modelData.myID, delete tracker[__oldID])
            console.log('removed', Object.keys(tracker))
        }
    }
}

<强>阐释:

Instantiator为模型中的每个条目创建QtObject。此QtObject存储对条目的模型数据的引用。 myID__oldID两个属性用于使Map (JSObject) tracker保持最新状态。

myID绑定到model.myID所以,只要这会改变,就会触发myID上的信号发生变化。现在我需要将地图中的键从旧值更改为新值。因此,我使用密钥__oldID删除条目,然后将__oldID更新为新的myID,并使用新密钥将对象添加回地图。

我不希望绑定__oldID,因此我将其分配到Component.onCompleted

当删除条目时,我也会从Map中删除对象和引用,因此我会尽可能保持地图清洁。

添加新条目后,Instantiator会自动为此添加新的QtObject

现在,您可以使用myIDO(1)中查询tracker[myID]Instantiator负责跟踪所有更改。只有在特定行中的模型发生更改时,它才会更改。

请注意,此方法会对您的内存产生影响,因为它基本上会在hashmap中复制您的模型。

为避免这种情况,您可以在C ++中实现ProxyModel,例如基于QIdentityProxyModel添加myID和实际模型索引的映射。处理dataChanged - 信号以使该地图保持最新状态。

PS:我希望至少myID是唯一的。否则像这样,你可能会失去一些参考。然后使用存储桶在地图中保留共享myID

的多个条目