项目场景:
需要表格记录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}";