我也刚遇到这个。然而,我没有用第三方库(或者我自己的库!)替换整个 Qt JSON 实现,而是拼凑了一个解决方案......
我与此相关的完整代码库过于广泛和详尽,无法在此处发布和解释。但是解决这一点的要点很简单。
首先,我使用 QVariantMap(或 QVariantHash)来收集我的数据,然后通过内置QJsonObject::fromVariantMap
或QJsonDocument::fromVariant
函数将其转换为 json。为了控制序列化,我定义了一个名为的类DataFormatOptions
,它有一个decimalPrecision
成员(并设置了对其他此类格式化选项的简单扩展..),然后我调用了一个函数toMagicVar
来为我的数据结构创建“魔术变体”以转换为 json字节。为了控制数字格式/精度toMagicVar
,将双精度和浮点数转换为所需格式的字符串,并用一些“魔术字节”包围字符串值。我的实际代码的编写方式,可以轻松地在我正在构建的地图/哈希的任何“级别”上执行此操作/通过递归处理格式化,但我省略了这些细节......
const QString NO_QUOTE( "__NO_QUOT__" );
QVariant toMagicVar( const QVariant &var, const DataFormatOptions &opt )
{
...
const QVariant::Type type( var.type() );
const QMetaType::Type metaType( (QMetaType::Type)type );
...
if( opt.decimalPrecision != DataFormatOptions::DEFAULT_PRECISION
&& (type == QVariant::Type::Double || metaType == QMetaType::Float) )
{
static const char FORMAT( 'f' );
static const QRegExp trailingPointAndZeros( "\\.?0+$" );
QString formatted( QString::number(
var.toDouble(), FORMAT, opt.decimalPrecision ) );
formatted.remove( trailingPointAndZeros );
return QVariant( QString( NO_QUOTE + formatted + NO_QUOTE ) );
}
...
}
请注意,我通过formatted.remove
. 如果您希望数据始终包含小数点后的 X 位,您可以选择跳过该步骤。(或者你可能想通过控制它DataFormatOptions
?)
一旦我有了要通过网络发送的 json 字节QByteArray
,我将删除魔术字节,因此我表示为带引号的字符串的数字再次成为 json 中的数字。
// This is where any "magic residue" is removed, or otherwise manipulated,
// to produce the desired final json bytes...
void scrubMagicBytes( QByteArray &bytes )
{
static const QByteArray EMPTY, QUOTE( "\"" ),
NO_QUOTE_PREFIX( QUOTE + NO_QUOTE.toLocal8Bit() ),
NO_QUOTE_SUFFIX( NO_QUOTE.toLocal8Bit() + QUOTE );
bytes.replace( NO_QUOTE_PREFIX, EMPTY );
bytes.replace( NO_QUOTE_SUFFIX, EMPTY );
}