【问题标题】:Get value for given index in QML LISTMODEL获取 QML LISTMODEL 中给定索引的值
【发布时间】:2021-08-26 05:59:36
【问题描述】:

我有一个如下所示的 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;

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

你能帮帮我吗? 谢谢

【问题讨论】:

  • 尝试ListElement {myId: "1", myValue: "12"} - : 而不是=。另外,请参阅此处了解如何彻底搜索列表模型:stackoverflow.com/questions/41991438/…
  • 不起作用:-(
  • 您查询的myId 会经常变化吗? ListModel的内容会经常变化吗?
  • 是的,总是不一样的!
  • 程序运行期间:数据会从ListModel追加和/或删除吗?对于ListModel 中的一个条目,值是否会随着时间的推移而保持不变,可能会全部变化,或者至少myId 不变?

标签: javascript qt qml


【解决方案1】:

如果您希望加快速度,则应将您的条目映射到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,因此,每当它发生变化时,它都会触发myIDchanged 上的信号。现在我需要将地图中的键从旧值更改为新值。因此,我使用键 __oldID 删除条目,然后将 __oldID 更新为新的 myID,并使用新键将对象重新添加到地图中。

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

当条目被删除时,我也会从Map 中删除对象和引用,所以我尽可能保持我的地图干净。

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


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

请注意,此方法会占用您的内存,因为它基本上会在 hashmap 中复制您的模型。

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

PS:我希望至少 myID 是独一无二的。否则像这样,您可能会丢失一些参考资料。然后使用存储桶,在映射中保留多个条目以共享myID's

【讨论】:

  • 谢谢@derM,非常有趣的答案!你能再解释一下代码吗?我是 QML 的新手..
  • 我试过了。有关更多信息,请阅读文档,或具体询问您的问题仍然存在。如果您希望这个问题的答案非常详细,您也可以考虑创建一个新问题,参考这个问题。
【解决方案2】:

你需要遍历你的模型来找到元素。

例子:

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);
    }
}

【讨论】:

  • 有效!谢谢!但是这种方法会大大降低程序的速度,我真的需要找到另一个解决方案:-(
猜你喜欢
  • 2012-05-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多