javascript 在 QML 中动态创建 ListModel

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25029180/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 03:46:53  来源:igfitidea点击:

Dynamically create ListModel in QML

javascriptruntimeqmlqt5

提问by Konstantin Utkin

When I need to create any QML component in runtime, I can use that guide: http://qt-project.org/doc/qt-5/qtqml-javascript-dynamicobjectcreation.html

当我需要在运行时创建任何 QML 组件时,我可以使用该指南:http: //qt-project.org/doc/qt-5/qtqml-javascript-dynamicobjectcreation.html

i.e. just call Qt.createComponent and component.createObject

即只调用 Qt.createComponent 和 component.createObject

But I couldn't find how to create ListModel at runtime? with qml, not in c++.

但是我找不到如何在运行时创建 ListModel?使用 qml,而不是 C++。

You can ask, why I need it. So, I have a nested ListModel: there is outer model, which delegates contained inner models. So when I'm calling outer_model.append({}), I must pass newly created ListModel for inner model. I cannot use statically defined inner modelin outer delegate, because I cannot access such model in runtime. By the way, can it be accessed somehow?

你可以问,为什么我需要它。所以,我有一个嵌套的 ListModel:有外部模型,其中委托包含内部模型。因此,当我调用 outer_model.append({}) 时,我必须为内部模型传递新创建的 ListModel 。我不能在外部委托中使用静态定义的内部模型,因为我无法在运行时访问这样的模型。顺便说一句,它可以以某种方式访问​​吗?

P.S. Maybe it's completely wrong idea to try managing models in javascript?

PS 也许尝试在 javascript 中管理模型是完全错误的想法?

采纳答案by folibis

Try this:

试试这个:

Component {
    id: someComponent
    ListModel {
    }
}

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

回答by islahul

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

我是一名编写 QtQuick 应用程序的 JS 开发人员,这是我尝试过多种解决方案的方法。

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 QJsonArrayas 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.

在 QML 中用 JavaScript 管理模型的简短回答是,这是一场噩梦。我建议你写一个 QAbstractListModel 的小子类,它内部使用QJsonArray作为其数据源,以便更容易理解 C++ 中的数据结构以及它在 QML 中的用法。按照此处的说明从 C++ 创建 QML 类型。

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

如果您仍想在 JavaScript 中执行此操作,另一种方法如下:

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()

然而,即使在使用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)

如果您主要关心的是在 ListModels 中有 ListModels,那么下面这个简单的事情对我有用(我认为 ListModels 中的对象数组和 ListModels 之间存在隐式类型转换)

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

回答by Kombinator

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