Dynamically create ListModel in QML

不问归期 提交于 2019-12-03 06:12:10

Try this:

Component {
    id: someComponent
    ListModel {
    }
}

function createModel(parent) {
    var newModel = someComponent.createObject(parent);
    return newModel;
}

I am a JS developer who writes QtQuick applications and this is something I have tried on with multiple solutions.

Short answer to managing models in JavaScript inside QML is that it's a nightmare. I would advice you to write a small sub-class of QAbstractListModel which internally uses QJsonArray as its data source, so that it makes it easier to understand the data structure in C++ as well as in its usage inside QML. Follow the instructions to create QML types from C++ here.

If you still want to do it inside JavaScript, another approach is the following:

function createNewList() {
    var newListModel = Qt.createQmlObject('import QtQuick 2.2; \
        ListModel {}', parent);
    return newListModel;
}

However this has some serious memory leak problems even after using gc()

If your primary concern is having ListModels inside ListModels, this following simple thing works for me (there is an implicit type conversion between array of objects and ListModels inside ListModels I think)

property ListModel items: ListModel {}

function addComplexItem() {
    items.append({
        "key": "People",
        "arr": [
            {
             "arrItemName": "John",
             "arrItemValue": 18,
            },
            {
             "arrItemName": "Kerry",
             "arrItemValue": 21,
            },
            {
             "arrItemName": "Mike",
             "arrItemValue": 19,
            }    
        ]});
}


// Usage
Component {
    id: viewDelegate

    Item {
        Text {
            text: "List of " + key
        }
        ListView {
            model: arr
            delegate: Rectangle {
                Text { 
                    text: arrItemName
                } 
            }
        }  
    }
}

I do the initialization like this:

dataObject_m1.initSystem= function() { // QML calls when ready 
  console.log( "ModulData_1.js func initSystem()");

  dataObject_m1.statisticsSystem= Qt.createQmlObject("import QtQuick 2.5; ListModel{}", dataObject_m1.parent, "dynamic_source" );
  dataObject_m1.statisticsSystem.objectName = "ModelSystem";
  dataObject_m1.statisticsSystem.append( { name: qsTr("System"), number: "", val: ""});
  dataObject_m1.statisticsSystem.append( { name: "S3500", number: "", val: ""});
  dataObject_m1.statisticsSystem.append( { name: "S3550", number: "", val: ""});
  dataObject_m1.statisticsSystem.append( { name: "S3551", number: "", val: ""});
  dataObject_m1.statisticsSystem.append( { name: "S9999", number: "", val: ""});
}    

And to update Data:

 var updateSystem = function ( numberMap , valMap) {
     console.log ("ModuleData_1.js: updateSystem" );

   for (var num in (numberMap )) {
      var j = dataObject_m1.idMap[num];
      dataObject_m1.statisticsSystem.set( j, { val : Map[num]});
      console.log ("number(" + numberMap[val]+ ") [" + String(j) + "]= numbeMap["+val+"]" )
  }
 for (var valx in (valMap)) {
     var k = dataObject_m1.idMap[valx];
     dataObject_m1.statisticsSystem.set( k, { bad : valMap[valx]});
     console.log ("val(" + valMap[valx]+ ") [" + String(k) + "]= valMap["+valx+"]" )
  }
}

Access fuction to model:

 var statisticsModelSystem= function()  {
    console.log ("ModulData_1.js: get statisticsModelSystem" );
    if ( typeof(dataObject_m1.statisticsSystem) !== 'object')
        console.error(" statisticsSystem is undefined ")

    return dataObject_m1.statisticsSystem;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!