【问题标题】:Build QVariant list from non-ordered data从无序数据构建 QVariant 列表
【发布时间】:2013-06-03 21:50:00
【问题描述】:

我有这组数据:

[ step:-1, name:"BaseName1",  value:v1 ]
[ step:-1, name:"BaseName2",  value:v2 ]
[ step:2,  name:"ParamName3", value:v3 ]
[ step:2,  name:"ParamName4", value:v4 ]
[ step:0,  name:"ParamName5", value:v5 ]
[ step:0,  name:"ParamName6", value:v6 ]
[ step:1,  name:"ParamName7", value:v7 ]
[ step:1,  name:"ParamName8", value:v8 ]

我想转换为 QVariant,如下所示:

[
    "BaseName1": v1,
    "BaseName2": v2,
    "steps": [{
            "ParamName5": v5,
            "ParamName6": v6
        }, {
            "ParamName7": v7,
            "ParamName8": v8
        }, {
            "ParamName3": v3,
            "ParamName4": v4
        }
    ]
]

我想应该是这样的:

QVariantMap params;
params["Base_param_1"] = value;
params["Base_param_2"] = value2;
params["steps"] = QVariantList();

但是对于数组,我需要对数据进行排序;这意味着我应该在params["steps"]步骤 1 和 3 之前插入步骤 0(步骤 2 应该为空)。
此外,不能对输入数据进行排序。

我尝试使用以下代码来实现:

struct Params{ 
    QString name;  
    QVariant value; 
    int step;/* -1 for base param */ 
};
QList<Params> _params = (...);

QVariantMap v_settings;
QVariantList v_steps;

for(int i=0; i<_params.size(); i++){
    const Param &param = _params[i];

    if( param.index == -1 ){
        v_settings.insert(param.name, param.value);
    }
    else {
        // if list too small, append empties to the list until it exists
        while( v_steps.size() < param.index ){
            QVariantMap map;
            v_steps.append(map);
        }

        v_steps.at(param.index).toMap().insert(param.name, param.value);
    }
}
v_settings.insert("steps", v_steps);

但是遇到此行时,代码有时会因索引超出范围而失败:

v_steps.at(param.index).toMap().insert(param.name, param.value);

所以我猜我的“用空地图填充”循环以某种方式失败了。 我该怎么办?

【问题讨论】:

    标签: c++ qt qt5 qvariant


    【解决方案1】:

    您的代码中有几个问题。

    “索引超出范围”问题发生是因为您没有向列表中添加足够的对象。你应该写

    while( v_steps.size() <= param.index ) {
    

    即将&lt; 替换为&lt;=。它将确保,例如在访问第 5 个元素之前,数组中将包含 6 个元素(元素从 0 开始计数,记得吗?)

    另一个问题是toMap().inserttoMap() 按值返回 QMap,而不是按引用。因此,在其上调用insert 毫无意义,因为它只是尚未分配给任何变量的临时值。 insert结束后会立即销毁,不会保存任何更改。

    我建议您使用QVector&lt;QVariantMap&gt; v_steps 来存储您的数据。在这种情况下QVectorQList 更好,因为resize() 它很容易。插入可以使用以下代码完成:

    v_steps[param.index].insert(param.name, param.value);
    

    那你需要转换成QVariantList:

    QVariantList v_steps_real;
    foreach(QVariantMap map, v_steps) {
      v_steps_real << map;
    }
    v_settings.insert("steps", v_steps_real);
    

    请注意,您可以使用 [] 运算符而不是 insert() 将值插入地图:

    map["key"] = value;
    

    【讨论】:

    • 成功了,谢谢。我只是想知道为什么没有办法为 QtJson “就地”修改数组的内容。感觉……不完整。
    • 您可以执行QVariantMap map = variant_list[i].toMap(); map[key] = value; variant_list[i] = map; 之类的操作 - 它会就地编辑 QVariantMap。不过,这会导致一些开销。
    猜你喜欢
    • 1970-01-01
    • 2015-01-04
    • 2014-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多