从非有序数据构建QVariant列表

时间:2013-06-07 14:32:11

标签: c++ qt qt5 qvariant

我有这组数据:

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

但对于数组,我需要订购数据;这意味着我应该在步骤1和3之前在params["steps"] 中插入步骤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);

所以我猜我的#34;填空地图&#34;以某种方式循环失败。 我该怎么办?

1 个答案:

答案 0 :(得分:1)

您的代码中存在多个问题。

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

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

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

另一个问题出在toMap().inserttoMap()按值返回QMap,而不是按引用返回。所以在它上面调用insert是没有意义的,因为它只是暂时的值而没有分配给任何变量。它将在insert结束后立即销毁,并且不会存储任何更改。

我建议您使用QVector<QVariantMap> v_steps来存储您的数据。在这种情况下,QVector优于QList,因为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; 将值插入地图中:

{{1}}