QJsonVariant is a tiny Qt/QtCore-only helper that converts QVariant trees to and from JSON or CBOR. It offers both one-shot helpers (fromJson, fromVariant) and streaming readers/writers so you can walk large payloads incrementally without building a full QJsonDocument or QCborValue in memory.
- Streaming-first API –
QJsonVariantReader,QCborVariantReader, and their writer counterparts let you pull values from anyQIODevice(files, sockets, buffers) while tracking progress and container depth. - Drop-in converters –
QJsonVariantWriter::fromVariant()and friends mirror Qt's convenience API but avoid extra conversions. - Symmetric JSON/CBOR support – the same
QVariantReadersemantics work for both formats, including string escaping, numeric parsing, and nested structures. - Fast & dependency-light – no Qt GUI modules required; benchmarks (see
tests/benchmark) compare favorably againstQJsonDocument,QCborValue, XML, andQDataStreamserialization.
| Format | Reader | Writer | Notes |
|---|---|---|---|
| JSON | QJsonVariantReader |
QJsonVariantWriter |
Optional compact/indented output, UTF-8 BOM skipping, works with QByteArray or any QIODevice. |
| CBOR | QCborVariantReader |
QCborVariantWriter |
Honors QCborStreamReader length hints and supports QCborValue::EncodingOptions (e.g., UseFloat16). |
- Qt 5.15+ or Qt 6.x (
Qt::Coreonly) - CMake 3.16+
- A compiler compatible with your Qt build (C++17 recommended)
# FetchContent, submodule, or local copy
add_subdirectory(external/QJsonVariant/src)
qt_add_executable(MyApp main.cpp)
target_link_libraries(MyApp PRIVATE Qt${QT_VERSION_MAJOR}::Core QJsonVariant)Copy the .h/.cpp files from src/ into your Qt project (CMake/qmake/Qbs) and include <qjsonvariantreader.h>, <qcborvariantwriter.h>, etc. A convenience umbrella header lives at src/QJsonVariant.
QVariantMap payload {{"name", "Alice"}, {"age", 42}};
QByteArray json = QJsonVariantWriter::fromVariant(payload, /*compact=*/true);
QVariant fromJson = QJsonVariantReader::fromJson(json);
QByteArray cbor = QCborVariantWriter::fromVariant(payload, QCborValue::UseFloat16);
QVariant fromCbor = QCborVariantReader::fromCbor(cbor);QJsonVariantReader reader(jsonData);
reader.enterContainer(); // enter the root object
while (reader.hasNext()) {
const QString key = reader.readString();
if (key == "tasks") {
reader.enterContainer();
while (reader.hasNext()) {
QVariant task = reader.read(); // task is a QVariantMap
// ... process task ...
}
reader.leaveContainer();
} else {
reader.read(); // consume and ignore this entry
}
}
reader.leaveContainer();QByteArray buffer;
QJsonVariantWriter writer(&buffer, /*compact=*/false);
writer.start();
writer.startMap();
writer.writeKeyValue("ok", true);
writer.writeValueSeparator();
writer.writeString("items");
writer.writeNameSeparator();
writer.startArray();
for (int value : {1, 2, 3}) {
writer.writeVariant(value);
if (value != 3)
writer.writeValueSeparator();
}
writer.endArray();
writer.endMap();The CBOR API mirrors the JSON writer (with QCborVariantWriter/QCborVariantReader) and accepts optional container lengths when known up front.
tests/json/tst_json.cpp&tests/cbor/tst_cbor.cppassert byte-for-byte parity with the official Qt JSON/CBOR helpers for a wide range of types (nulls, nested maps,QDateTime, Unicode, etc.).tests/benchmark/tst_benchmark.cpprunsQTestbenchmarks that compare QJsonVariant againstQJsonDocument,QCborValue, Qt XML,QDataStream, and the streaming APIs on a 10k-task workload.
| Format | Serialization Time | Deserialization Time | Serialized Size |
|---|---|---|---|
| QDataStream | 1 ms | 1 ms | 1127 KB |
| XML | 9.5 ms | 25 ms | 1757 KB |
| JSON | 23 ms | 9.7 ms | 2005 KB |
| JsonVariantStream | 10 ms | 5 ms | 2005 KB |
| CBOR | 18 ms | 33 ms | 1511 KB |
| CBORStream | 6.5 ms | 6.2 ms | 1690 KB |
| CBORVariantStream | 7.5 ms | 6.7 ms | 1690 KB |
src/ library implementation + umbrella header
tests/json JSON parity tests
tests/cbor CBOR parity tests
tests/benchmark Performance + serialization comparisons
QJsonVariant is licensed under the MIT License (see LICENSE). Issues and pull requests are welcome—whether it is performance work, new helpers, or additional documentation.