项目场景:
需要表格记录json数据,使用Qtreeview显示并修改,使用开源的第三方类QJsonModel,即可快速完成。
问题描述:
使用中发现一个问题:当Qtreeview修改完毕,从Model获取保存后的Json数据时,发生了异常,
例如当时传入的数据是:
"{\"ID\":555, \"AGE\":30, \"NUMBER\":11}";
修改555->666,得到的数据却是:
"{\"ID\":\"666\", \"AGE\":\"30\", \"NUMBER\":\"11\"}";
原因分析:
猜测model的返回,将value和key都当做了String处理,所以判断是arrayToJson()或者objectToJson()的问题,进一步发现都使用了genJson(mRootItem),继续看发现原代码中只对bool做了处理,其余一律默认String。
QJsonValue QJsonModel::genJson(QJsonTreeItem *item) const
{
auto type = item->type();
int nchild = item->childCount();
if (QJsonValue::Object == type) {
QJsonObject jo;
for (int i = 0; i < nchild; ++i) {
auto ch = item->child(i);
auto key = ch->key();
jo.insert(key, genJson(ch));
}
return jo;
} else if (QJsonValue::Array == type) {
QJsonArray arr;
for (int i = 0; i < nchild; ++i) {
auto ch = item->child(i);
arr.append(genJson(ch));
}
return arr;
} else {
QJsonValue va;
switch(item->value().type()) {
case QVariant::Bool: {
va = item->value().toBool();
break;
}
default:
va = item->value().toString();
break;
}
(item->value());
return va;
}
}
解决方案:
更改判断条件,具体的根据需要填充不同数据类型,这样返回就是正确的值了,更改后的代码如下:
QJsonValue QJsonModel::genJson(QJsonTreeItem *item) const
{
auto type = item->type();
int nchild = item->childCount();
if (QJsonValue::Object == type) {
QJsonObject jo;
for (int i = 0; i < nchild; ++i) {
auto ch = item->child(i);
auto key = ch->key();
jo.insert(key, genJson(ch));
}
return jo;
} else if (QJsonValue::Array == type) {
QJsonArray arr;
for (int i = 0; i < nchild; ++i) {
auto ch = item->child(i);
arr.append(genJson(ch));
}
return arr;
} else {
QJsonValue va;
switch(item->value().type()) {
case QVariant::Bool: {
va = item->value().toBool();
break;
}
case QVariant::Int:
va = item->value().toInt();
break;
case QVariant::UInt:
case QVariant::LongLong:{
va = item->value().toLongLong();
break;
}
case QVariant::ULongLong:
case QVariant::Double: {
va = item->value().toDouble();
break;
}
// 添加其他 QVariant 类型的处理
default: {
va = item->value().toString();
break;
}
}
return va;
}
}
这样就可以通过QByteArray json(bool compact = false)这个方法得到正确的数据类型的值。
"{\"ID\":666, \"AGE\":30, \"NUMBER\":11}";