Динамически создавать ListModel в QML

когда мне нужно создать любой компонент QML во время выполнения, я могу использовать это руководство: http://qt-project.org/doc/qt-5/qtqml-javascript-dynamicobjectcreation.html

т. е. просто вызовите Qt.createComponent и компонентов.функция createobject

но я не мог найти, как создать ListModel во время выполнения? с qml, а не на c++.

вы можете спросить, зачем мне это нужно. Итак, у меня есть вложенная ListModel: есть внешняя модель, которые делегаты содержали внутренняя модели. Поэтому, когда я вызываю outer_model.append ({}), я должен передать недавно созданный ListModel для внутренняя модель. Я не могу использовать статически определенный внутренняя модель во внешнем делегате, потому что я не могу получить доступ к такой модели во время выполнения. Кстати, можно к нему как-то получить доступ?

P. S. Может это совершенно неправильная идея попробовать управлять моделями в JavaScript?

3 ответов


попробуйте это:

Component {
    id: someComponent
    ListModel {
    }
}

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

Я разработчик JS, который пишет приложения QtQuick, и это то, что я пробовал с несколькими решениями.

короткий ответ на управление моделями в JavaScript внутри QML-это Это кошмар. Я бы посоветовал вам написать небольшой подкласс QAbstractListModel, который внутренне использует QJsonArray как свой источник данных, так, что он сделает его более легким понять структуру данных в C++ так же, как в своем использовании внутри QML. Следуйте инструкции по созданию типов QML из C++ здесь.

Если вы все еще хотите сделать это в JavaScript, другой подход заключается в следующем:

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

однако это имеет некоторые серьезные проблемы с утечкой памяти даже после использования gc ()

Если ваша основная проблема заключается в наличии ListModels внутри ListModels, для меня работает следующая простая вещь (существует неявное преобразование типов между массивом объектов и ListModels внутри ListModels I думаю)

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

Я делаю инициализацию такое:

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

и чтобы обновлять данные:

 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+"]" )
  }
}

функция доступа к модели:

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