【问题标题】:Pass an Array in ListModel在 ListModel 中传递一个数组
【发布时间】:2017-12-22 17:42:52
【问题描述】:

我想知道如何在 ListModel 中传递一个数组?

好的,在 QML 中,我有一个 ListView,我将其设置为 ListModel,如下所示:

model: ListModel
{
    id: myList   
    ListElement 
    {
        name: ""
        card: 0
        books: []
    }

}

我可以使用:

myList.append({name:"terry", card:00100, books:["024589","865976","879582","215645"]}); 

但是当我尝试在屏幕上输出它时,我得到了这个。

{
    "card": 00100
    "books": {
        "objectName": "",
        "count": 4,
        "dynamicRoles": false
     },
    "name": "terry",
    "name": "terry"
}

我不知道为什么我会得到 2 个名字!以及如何获得书籍的价值?

我查阅了ListModelListElement 的QML 文档,找不到任何与传递数组相关的内容,所有示例都是整数或字符串。

知道如何获取日期吗?
我确实通过使用Component.onCompleted:{} 调用 Delegate 中的数组来解决它,但我认为这不是一个好的/正确的方法,因为 Delegate 不负责保存数据并且应该在模型中完成,如果我错了,请纠正我。

感谢您的宝贵时间。

Edit01:感谢您的回复,这是我需要数组的原因: 我在 Delegate 中有一个 ComboBox,如下所示:

delegate: Rectangle
    {
     id: rowID
     width: 50
     height: 40
     color: "#323232"
     Row
     {
         anchors.fill: parent
         anchors.leftMargin: 10
         anchors.rightMargin: 10
         Label{
             id: nameID
             text: name
             font.pixelSize: 12
             width: 200
             wrapMode: Text.WrapAnywhere
             anchors.verticalCenter: parent.verticalCenter
             color: "#999"
         }

         Label{
             anchors.verticalCenter: parent.verticalCenter
             text: "out:"
             font.pixelSize: 12
             color: "#999"
         }

         ComboBox{
             id: booksID
             height: 20
             width: 50
             model: books
             anchors.verticalCenter: parent.verticalCenter
         }
     }
}

如您所见,我将 name 提供给 Labelid: nameID)并且我想提供 bookComboBox (id: booksID) 具有 model,如果我将 books 键设为 ListElement 如何提供所有值?

在 QML ListModelListElement 文档中没有提到任何关于获取所有密钥值的内容吗?它只支持基于索引号的get(int index)

【问题讨论】:

  • 只是快速浏览文档的猜测,在模型中尝试books: [ ListElement "" ]
  • @T4rk1n 我得到了这个UiError: widget creation failed 但是当我使 ListElement 等于 JSON 时,对吗?这意味着我需要给它键和值,但是使用 Array 听起来更简单直接。

标签: javascript qml


【解决方案1】:

作为使用 ListModel 和 ListElement 的替代方法,您还可以查看 QSyncable JsonListModel QML 类型。 (这是 Ben Lau 的一个开源组件,你可以在 GitHub 上找到它:https://github.com/benlau/qsyncable

JsonListModel 是一种特殊的 ListModel 类型,可以处理 JSON 数组,例如在您的 QML 中创建或从 REST 服务中获取。它会自动将 JSON 同步到 QML ListModel,因此使用起来非常方便:

ListView {
        id: listView
        anchors.fill: parent

        // property for json data, used as source for JsonListModel
        property var jsonData: []

        // use JsonListModel as model
        model: JsonListModel {
          source: listView.jsonData
          keyField: "id"
        }

        // delegate
        delegate: DelegateItem { /* ... */ }
}

您还可以在此处找到其工作原理的综合指南:JsonListModel guide

【讨论】:

    【解决方案2】:

    你想要类似的东西吗:

    Rectangle {
    
    id: root
    visible: true
    width: 360
    height: 360
    
    ListModel
    {
        id: myList
        ListElement {
               name: "Story"
               card: 3
               books: [
                   ListElement { bookName: "Story 1" },
                   ListElement { bookName: "Story 2" },
                   ListElement { bookName: "Story 3" }
               ]
           }
           ListElement {
               name: "Novel"
               card: 3
               books: [
                   ListElement { bookName: "Novel 1" },
                   ListElement { bookName: "Novel 2" },
                   ListElement { bookName: "Novel 3" }
               ]
           }
    }
    
    
    Component {
        id: displayDelegate
        Rectangle
            {
             id: rowID
             width: 300 //50
             height: 40
             color: "#323232"
             border.color: "white"
             Row
             {
                 anchors.fill: parent
                 anchors.leftMargin: 10
                 anchors.rightMargin: 10
                 Text{
                     id: nameID
                     text: name
                     font.pixelSize: 12
                     width: 50 //200
                     wrapMode: Text.WrapAnywhere
                     /*anchors.verticalCenter: parent.verticalCenter*/
                     color: "white"//"#999"
                 }
    
                 Text{
                     /*anchors.verticalCenter: parent.verticalCenter*/
                     text: "out:"
                     font.pixelSize: 12
                     color: "white"//"#999"
                 }
    
                 /*ComboBox{
                     id: booksID
                     height: 20
                     width: 50
                     model: books
                     anchors.verticalCenter: parent.verticalCenter
                 }*/
                 Repeater {
                     model: books
                     Text { text: bookName + "\t"; color: "white" }
                 }
             }
        }
    }
    
    ListView {
        id: disp
        anchors.fill: parent
        model: myList
        delegate: displayDelegate
    }
    
    }
    

    我修改了您分享的几行代码。我不确定您的 ComboBox 实现。因此,我使用了自己的 Repeater 实现。您可以尝试执行并查看结果。

    【讨论】:

      【解决方案3】:

      你做错了。数组成员必须是ListElement

      ListModel {
          id: mod
          ListElement {
              name: "ali"
              dic: [ ListElement{text:"asad-o-llah"; code: 14}, ListElement{text:"aboo torab"; code: 72}, ListElement{text:"amir al-momenin"; code: 110}]
          }
      }
      
      ListView {
          model: mod
          anchors.fill: parent
          delegate: Component {
              Rectangle {
                  width: parent.width; height: 50
                  Row {
                      Text {
                          text: name
                      }
                      ComboBox {
                          width: 100; height: 30
                          model: dic        //<-- set dic as model for combo box
                          textRole: "text"  //<-- important!
                          onCurrentIndexChanged: {
                              console.log("current code is "+model.get(currentIndex).code);   //<-- get code value
                          }
                      }
                  }
              }
          }
      }
      Component.onCompleted: {
          var v = mod.get(0).dic.get(0).value;    //<-- sample usage
          console.log(v);
      }
      

      【讨论】:

      • 是的,效果很好。但这有点像带有键和值的字典/Json,假设我想将它用于 Delegate 中的 ComboBox,如何在 ComboBox 模型中提供 ListElement 值? ListElement 没有任何选项可以提供所有键的值吗?
      • 我更新了答案以解释如何在 ComboBox 中使用子模型。
      • 是的,这就是我要找的textRole,非常感谢:)
      • @S.M.Mousavi 如何使用append() 添加新元素?
      • 在所有地方的 SE.Ubuntu 上找到了答案:askubuntu.com/a/714306
      猜你喜欢
      • 2018-12-24
      • 1970-01-01
      • 2013-04-08
      • 2013-09-20
      • 2011-04-05
      • 2021-08-25
      • 2021-03-06
      • 2015-09-19
      • 2018-03-29
      相关资源
      最近更新 更多