diff options
Diffstat (limited to 'examples/corelib')
19 files changed, 216 insertions, 65 deletions
diff --git a/examples/corelib/CMakeLists.txt b/examples/corelib/CMakeLists.txt index aff53c8202..a4b659ab83 100644 --- a/examples/corelib/CMakeLists.txt +++ b/examples/corelib/CMakeLists.txt @@ -1,4 +1,3 @@ -add_subdirectory(bindableproperties) add_subdirectory(ipc) add_subdirectory(mimetypes) add_subdirectory(serialization) @@ -7,3 +6,6 @@ add_subdirectory(platform) if(QT_FEATURE_thread) add_subdirectory(threads) endif() +if(QT_FEATURE_widgets) + add_subdirectory(bindableproperties) +endif() diff --git a/examples/corelib/serialization/cbordump/doc/images/cbordump.png b/examples/corelib/serialization/cbordump/doc/images/cbordump.png Binary files differnew file mode 100644 index 0000000000..72232c1a95 --- /dev/null +++ b/examples/corelib/serialization/cbordump/doc/images/cbordump.png diff --git a/examples/corelib/serialization/cbordump/doc/src/cbordump.qdoc b/examples/corelib/serialization/cbordump/doc/src/cbordump.qdoc new file mode 100644 index 0000000000..c3565e184d --- /dev/null +++ b/examples/corelib/serialization/cbordump/doc/src/cbordump.qdoc @@ -0,0 +1,52 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! + \example serialization/cbordump + \title Cbordump Example + + \brief The Cbordump example demonstrates how to parse files in CBOR-format. + + The Cbordump example reads from files or stdin content in CBOR-format and + dumps the decoded content to stdout. The cbordump utility can output in + CBOR diagnostic notation (which is similar to JSON), or it can have a + verbose output where each byte input is displayed with the encoding beside + it. This example shows how to use the QCborStreamReader class directly to + parse CBOR content. + + \sa QCborStreamReader + + \image cbordump.png + + \section1 The Cbordumper Class + + The Cbordumper class contains a QCborStreamReader object that is + initialized using the QFile object argument passed to the CborDumper + constructor. Based on the arguments the dump function calls either + dumpOne() or dumpOneDetailed() to dump the contents to stdout, + + \snippet serialization/cbordump/main.cpp 0 + + \section2 The dumpOne() Function + + The type() function of the QCborStreamReader is used in a switch statement + to print out for each type. If the type is an array or map, the content is + iterated upon, and for each entry the dumpOne() function is called + recursively with a higher indentation argument. If the type is a tag, it + is printed out and dumpOne() is called once without increasing the + indentation argument. + + \section2 The dumpOneDetailed() Function + + This function dumps out both the incoming bytes and the decoded contents + on the same line. It uses lambda functions to print out the bytes and + decoded content, but otherwise has a similar structure as dumpOne(). + + \section1 CborDescription + + The tagDescriptions table, describing the CBOR-tags available, is + automatically generated from an XML-file available from the iana.org + website. + + \sa {CBOR Support in Qt} + */ diff --git a/examples/corelib/serialization/cbordump/main.cpp b/examples/corelib/serialization/cbordump/main.cpp index 126a5c5833..ed079d6a97 100644 --- a/examples/corelib/serialization/cbordump/main.cpp +++ b/examples/corelib/serialization/cbordump/main.cpp @@ -87,6 +87,7 @@ enum { Value64Bit = 27 }; +//! [0] struct CborDumper { enum DumpOption { @@ -113,6 +114,7 @@ private: qint64 offset = 0; DumpOptions opts; }; +//! [0] Q_DECLARE_OPERATORS_FOR_FLAGS(CborDumper::DumpOptions) static int cborNumberSize(quint64 value) @@ -701,7 +703,7 @@ int main(int argc, char *argv[]) QStringList files = parser.positionalArguments(); if (files.isEmpty()) files << "-"; - for (const QString &file : qAsConst(files)) { + for (const QString &file : std::as_const(files)) { QFile f(file); if (file == "-" ? f.open(stdin, QIODevice::ReadOnly) : f.open(QIODevice::ReadOnly)) { if (files.size() > 1) diff --git a/examples/corelib/serialization/convert/cborconverter.cpp b/examples/corelib/serialization/convert/cborconverter.cpp index 0f49de2551..8c88d42af3 100644 --- a/examples/corelib/serialization/convert/cborconverter.cpp +++ b/examples/corelib/serialization/convert/cborconverter.cpp @@ -57,6 +57,7 @@ QT_END_NAMESPACE static QVariant convertCborValue(const QCborValue &value); +//! [0] static QVariant convertCborMap(const QCborMap &map) { VariantOrderedMap result; @@ -83,8 +84,9 @@ static QVariant convertCborValue(const QCborValue &value) return convertCborMap(value.toMap()); return value.toVariant(); } - +//! [0] enum TrimFloatingPoint { Double, Float, Float16 }; +//! [1] static QCborValue convertFromVariant(const QVariant &v, TrimFloatingPoint fpTrimming) { if (v.userType() == QMetaType::QVariantList) { @@ -114,6 +116,7 @@ static QCborValue convertFromVariant(const QVariant &v, TrimFloatingPoint fpTrim return QCborValue::fromVariant(v); } +//! [1] QString CborDiagnosticDumper::name() { @@ -216,6 +219,7 @@ bool CborConverter::probeFile(QIODevice *f) return f->isReadable() && f->peek(3) == QByteArray("\xd9\xd9\xf7", 3); } +//! [2] QVariant CborConverter::loadFile(QIODevice *f, Converter *&outputConverter) { const char *ptr = nullptr; @@ -250,9 +254,11 @@ QVariant CborConverter::loadFile(QIODevice *f, Converter *&outputConverter) return contents.toVariant(); return convertCborValue(contents); } - +//! [2] +//! [3] void CborConverter::saveFile(QIODevice *f, const QVariant &contents, const QStringList &options) { + //! [3] bool useSignature = true; bool useIntegers = true; enum { Yes, No, Always } useFloat16 = Yes, useFloat = Yes; @@ -311,7 +317,7 @@ void CborConverter::saveFile(QIODevice *f, const QVariant &contents, const QStri qPrintable(s), optionHelp); exit(EXIT_FAILURE); } - + //! [4] QCborValue v = convertFromVariant(contents, useFloat16 == Always ? Float16 : useFloat == Always ? Float : Double); QCborStreamWriter writer(f); @@ -327,4 +333,4 @@ void CborConverter::saveFile(QIODevice *f, const QVariant &contents, const QStri opts |= QCborValue::UseFloat16; v.toCbor(writer, opts); } - +//! [4] diff --git a/examples/corelib/serialization/convert/doc/images/convert.png b/examples/corelib/serialization/convert/doc/images/convert.png Binary files differnew file mode 100644 index 0000000000..8d6816a626 --- /dev/null +++ b/examples/corelib/serialization/convert/doc/images/convert.png diff --git a/examples/corelib/serialization/convert/doc/src/convert.qdoc b/examples/corelib/serialization/convert/doc/src/convert.qdoc new file mode 100644 index 0000000000..dc3264a469 --- /dev/null +++ b/examples/corelib/serialization/convert/doc/src/convert.qdoc @@ -0,0 +1,80 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! + \example serialization/convert + \title Convert Example + + \brief The Convert example demonstrates how to convert between different + serialization formats. + + The Convert example converts between the serialization formats JSON, CBOR, + XML, QDataStream and text. It can also auto detect the format being used. + Not all formats support both input and output, and they have different + sets of which types they support. QDataStream and XML are the richest, + followed by CBOR, then JSON, and then the plain text one. + + \image convert.png + + \section1 The Converter Class + + The Converter class is the abstract superclass for all the converters to + and from all the formats. They all convert to and from the QVariant class, + which is used to represent all the datastructures internally. + The name() function returns the name of the converter. The directions() + function is used to determine if a converter can be used for input, output, + or both. The outputOptions() and optionsHelp() functions are used to get + and query which options are used by the different converters. The + probeFile() function is used to determine if a file has the same file + format as the converter. The loadFile() function deserializes the given + file, while the saveFile() serializes to the given file. + + \section1 The CborConverter Class + + The CborConverter class shows how to serialize to and from the CBOR-format. + There is also a CborDiagnosticDumper class to output in CBOR diagnostic + notation. That is similar to JSON, but not exactly, because it allows + displaying the contents of a CBOR stream losslessly, while a conversion + to JSON is lossy. + + The convertCborValue() function is used to convert a QCborValue to a + QVariant. It uses the helper functions convertCborMap() and + convertCborArray(). + \snippet serialization/convert/cborconverter.cpp 0 + + A CBOR-file is read using loadFile() function. + \snippet serialization/convert/cborconverter.cpp 2 + + The convertFromVariant() function is used to convert a QVariant to a + QCborValue. + \snippet serialization/convert/cborconverter.cpp 1 + + A CBOR-file is written using the saveFile() function. + \snippet serialization/convert/cborconverter.cpp 3 + \snippet serialization/convert/cborconverter.cpp 4 + + \sa {CBOR Support in Qt} + + \section1 The DataStreamConverter Class + + The DataStreamConverter class is used to serialize to and from the + QDataStream format. There is also the DataStreamDumper class for outputting + the data lossless in a non-standardized human readable format. + + \section1 The JsonConverter Class + + The JsonConverter class is used to serialize to and from the JSON-format. + \sa {JSON Support in Qt} + + \section1 The XmlConverter Class + + The XmlConverter class is used to serialize to and from the XML-format. + + \section1 The TextConverter Class + + The TextConverter class is used to serialize to and from a text format. + + \section1 The NullConverter Class + + The NullConverter class is an output serializer that does nothing. +*/ diff --git a/examples/corelib/serialization/convert/main.cpp b/examples/corelib/serialization/convert/main.cpp index c234a28f1b..00c626e1c8 100644 --- a/examples/corelib/serialization/convert/main.cpp +++ b/examples/corelib/serialization/convert/main.cpp @@ -31,7 +31,7 @@ int main(int argc, char *argv[]) QStringList inputFormats; QStringList outputFormats; - for (Converter *conv : qAsConst(*availableConverters)) { + for (Converter *conv : std::as_const(*availableConverters)) { auto direction = conv->directions(); QString name = conv->name(); if (direction & Converter::In) @@ -82,7 +82,7 @@ int main(int argc, char *argv[]) if (parser.isSet(formatOptionsOption)) { QString format = parser.value(formatOptionsOption); - for (Converter *conv : qAsConst(*availableConverters)) { + for (Converter *conv : std::as_const(*availableConverters)) { if (conv->name() == format) { const char *help = conv->optionsHelp(); if (help) @@ -100,7 +100,7 @@ int main(int argc, char *argv[]) Converter *inconv = nullptr; QString format = parser.value(inputFormatOption); if (format != "auto") { - for (Converter *conv : qAsConst(*availableConverters)) { + for (Converter *conv : std::as_const(*availableConverters)) { if (conv->name() == format) { inconv = conv; break; @@ -116,7 +116,7 @@ int main(int argc, char *argv[]) Converter *outconv = nullptr; format = parser.value(outputFormatOption); if (format != "auto") { - for (Converter *conv : qAsConst(*availableConverters)) { + for (Converter *conv : std::as_const(*availableConverters)) { if (conv->name() == format) { outconv = conv; break; @@ -155,7 +155,7 @@ int main(int argc, char *argv[]) if (!inconv) { // probe the input to find a file format - for (Converter *conv : qAsConst(*availableConverters)) { + for (Converter *conv : std::as_const(*availableConverters)) { if (conv->directions() & Converter::In && conv->probeFile(&input)) { inconv = conv; break; @@ -170,7 +170,7 @@ int main(int argc, char *argv[]) if (!outconv) { // probe the output to find a file format - for (Converter *conv : qAsConst(*availableConverters)) { + for (Converter *conv : std::as_const(*availableConverters)) { if (conv->directions() & Converter::Out && conv->probeFile(&output)) { outconv = conv; break; diff --git a/examples/corelib/serialization/savegame/character.cpp b/examples/corelib/serialization/savegame/character.cpp index 43be084d3e..7be737f308 100644 --- a/examples/corelib/serialization/savegame/character.cpp +++ b/examples/corelib/serialization/savegame/character.cpp @@ -6,10 +6,8 @@ #include <QMetaEnum> #include <QTextStream> -Character::Character() : - mLevel(0), - mClassType(Warrior) { -} +Character::Character() + = default; Character::Character(const QString &name, int level, diff --git a/examples/corelib/serialization/savegame/character.h b/examples/corelib/serialization/savegame/character.h index dfb3837331..4dc25139a6 100644 --- a/examples/corelib/serialization/savegame/character.h +++ b/examples/corelib/serialization/savegame/character.h @@ -11,7 +11,7 @@ //! [0] class Character { - Q_GADGET; + Q_GADGET public: enum ClassType { @@ -37,8 +37,8 @@ public: void print(int indentation = 0) const; private: QString mName; - int mLevel; - ClassType mClassType; + int mLevel = 0; + ClassType mClassType = Warrior; }; //! [0] diff --git a/examples/corelib/serialization/savegame/doc/src/savegame.qdoc b/examples/corelib/serialization/savegame/doc/src/savegame.qdoc index 0246ae48bb..5302582fcc 100644 --- a/examples/corelib/serialization/savegame/doc/src/savegame.qdoc +++ b/examples/corelib/serialization/savegame/doc/src/savegame.qdoc @@ -158,5 +158,5 @@ human-readable JSON files, but you also have the option to use a binary format if it's required, \e without rewriting any code. - \sa {JSON Support in Qt}, {Data Storage} + \sa {JSON Support in Qt}, {CBOR Support in Qt}, {Data Input Output} */ diff --git a/examples/corelib/serialization/savegame/game.cpp b/examples/corelib/serialization/savegame/game.cpp index 111fbfc6ea..a2427ee124 100644 --- a/examples/corelib/serialization/savegame/game.cpp +++ b/examples/corelib/serialization/savegame/game.cpp @@ -121,8 +121,8 @@ void Game::read(const QJsonObject &json) QJsonArray levelArray = json["levels"].toArray(); mLevels.clear(); mLevels.reserve(levelArray.size()); - for (int levelIndex = 0; levelIndex < levelArray.size(); ++levelIndex) { - QJsonObject levelObject = levelArray[levelIndex].toObject(); + for (const QJsonValue &v : levelArray) { + QJsonObject levelObject = v.toObject(); Level level; level.read(levelObject); mLevels.append(level); diff --git a/examples/corelib/serialization/savegame/game.h b/examples/corelib/serialization/savegame/game.h index 266e764a80..0e91343d27 100644 --- a/examples/corelib/serialization/savegame/game.h +++ b/examples/corelib/serialization/savegame/game.h @@ -4,12 +4,12 @@ #ifndef GAME_H #define GAME_H -#include <QJsonObject> -#include <QList> - #include "character.h" #include "level.h" +#include <QJsonObject> +#include <QList> + //! [0] class Game { diff --git a/examples/corelib/serialization/savegame/level.cpp b/examples/corelib/serialization/savegame/level.cpp index 04edadf7f6..c2f88c3434 100644 --- a/examples/corelib/serialization/savegame/level.cpp +++ b/examples/corelib/serialization/savegame/level.cpp @@ -35,8 +35,8 @@ void Level::read(const QJsonObject &json) QJsonArray npcArray = json["npcs"].toArray(); mNpcs.clear(); mNpcs.reserve(npcArray.size()); - for (int npcIndex = 0; npcIndex < npcArray.size(); ++npcIndex) { - QJsonObject npcObject = npcArray[npcIndex].toObject(); + for (const QJsonValue &v : npcArray) { + QJsonObject npcObject = v.toObject(); Character npc; npc.read(npcObject); mNpcs.append(npc); diff --git a/examples/corelib/serialization/savegame/level.h b/examples/corelib/serialization/savegame/level.h index 4c0a8aed89..e09e2c9f3c 100644 --- a/examples/corelib/serialization/savegame/level.h +++ b/examples/corelib/serialization/savegame/level.h @@ -4,17 +4,17 @@ #ifndef LEVEL_H #define LEVEL_H +#include "character.h" + #include <QJsonObject> #include <QList> -#include "character.h" - //! [0] class Level { public: Level() = default; - Level(const QString &name); + explicit Level(const QString &name); QString name() const; diff --git a/examples/corelib/serialization/savegame/main.cpp b/examples/corelib/serialization/savegame/main.cpp index c9e713c126..408b08dbc9 100644 --- a/examples/corelib/serialization/savegame/main.cpp +++ b/examples/corelib/serialization/savegame/main.cpp @@ -1,10 +1,11 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause +#include "game.h" + #include <QCoreApplication> #include <QTextStream> -#include "game.h" //! [0] int main(int argc, char *argv[]) { diff --git a/examples/corelib/threads/doc/src/mandelbrot.qdoc b/examples/corelib/threads/doc/src/mandelbrot.qdoc index b8a5930d8c..23633e17dc 100644 --- a/examples/corelib/threads/doc/src/mandelbrot.qdoc +++ b/examples/corelib/threads/doc/src/mandelbrot.qdoc @@ -13,11 +13,11 @@ \image mandelbrot-example.png Screenshot of the Mandelbrot example - The heavy computation here is the Mandelbrot set, probably the - world's most famous fractal. These days, while sophisticated - programs such as \l{http://matek.hu/xaos/doku.php}{XaoS} that provide real-time zooming in the - Mandelbrot set, the standard Mandelbrot algorithm is just slow - enough for our purposes. + The heavy computation here is the Mandelbrot set, probably the world's most + famous fractal. These days, while sophisticated programs, such as + \l{https://xaos-project.github.io/}{XaoS}, provide real-time zooming in + the Mandelbrot set, the standard Mandelbrot algorithm is just slow enough + for our purposes. In real life, the approach described here is applicable to a large set of problems, including synchronous network I/O and diff --git a/examples/corelib/threads/doc/src/waitconditions.qdoc b/examples/corelib/threads/doc/src/waitconditions.qdoc index 90f911aab3..ae9e767c13 100644 --- a/examples/corelib/threads/doc/src/waitconditions.qdoc +++ b/examples/corelib/threads/doc/src/waitconditions.qdoc @@ -109,7 +109,7 @@ thread is the only one that can do anything; the consumer is blocked waiting for the \c bufferNotEmpty condition to be signalled (\c numUsedBytes is 0). Once the producer has put one - byte in the buffer, \c numUsedBytes is \c BufferSize - 1 and the + byte in the buffer, \c numUsedBytes is strictly greater than 0, and the \c bufferNotEmpty condition is signalled. At that point, two things can happen: Either the consumer thread takes over and reads that byte, or the producer gets to produce a second byte. diff --git a/examples/corelib/threads/waitconditions/waitconditions.cpp b/examples/corelib/threads/waitconditions/waitconditions.cpp index 72b9ed39a5..bdc24acd8c 100644 --- a/examples/corelib/threads/waitconditions/waitconditions.cpp +++ b/examples/corelib/threads/waitconditions/waitconditions.cpp @@ -1,21 +1,28 @@ // Copyright (C) 2016 The Qt Company Ltd. +// Copyright (C) 2022 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause -#include <QtCore> +#include <QCoreApplication> +#include <QMutex> +#include <QMutexLocker> +#include <QObject> +#include <QRandomGenerator> +#include <QThread> +#include <QWaitCondition> #include <stdio.h> #include <stdlib.h> //! [0] -const int DataSize = 100000; +constexpr int DataSize = 100000; +constexpr int BufferSize = 8192; -const int BufferSize = 8192; +QMutex mutex; // protects the buffer and the counter char buffer[BufferSize]; +int numUsedBytes; QWaitCondition bufferNotEmpty; QWaitCondition bufferNotFull; -QMutex mutex; -int numUsedBytes = 0; //! [0] //! [1] @@ -23,24 +30,28 @@ class Producer : public QThread //! [1] //! [2] { public: - Producer(QObject *parent = NULL) : QThread(parent) + explicit Producer(QObject *parent = nullptr) + : QThread(parent) { } +private: void run() override { for (int i = 0; i < DataSize; ++i) { - mutex.lock(); - if (numUsedBytes == BufferSize) - bufferNotFull.wait(&mutex); - mutex.unlock(); + { + const QMutexLocker locker(&mutex); + while (numUsedBytes == BufferSize) + bufferNotFull.wait(&mutex); + } buffer[i % BufferSize] = "ACGT"[QRandomGenerator::global()->bounded(4)]; - mutex.lock(); - ++numUsedBytes; - bufferNotEmpty.wakeAll(); - mutex.unlock(); + { + const QMutexLocker locker(&mutex); + ++numUsedBytes; + bufferNotEmpty.wakeAll(); + } } } }; @@ -50,32 +61,32 @@ public: class Consumer : public QThread //! [3] //! [4] { - Q_OBJECT public: - Consumer(QObject *parent = NULL) : QThread(parent) + explicit Consumer(QObject *parent = nullptr) + : QThread(parent) { } +private: void run() override { for (int i = 0; i < DataSize; ++i) { - mutex.lock(); - if (numUsedBytes == 0) - bufferNotEmpty.wait(&mutex); - mutex.unlock(); + { + const QMutexLocker locker(&mutex); + while (numUsedBytes == 0) + bufferNotEmpty.wait(&mutex); + } fprintf(stderr, "%c", buffer[i % BufferSize]); - mutex.lock(); - --numUsedBytes; - bufferNotFull.wakeAll(); - mutex.unlock(); + { + const QMutexLocker locker(&mutex); + --numUsedBytes; + bufferNotFull.wakeAll(); + } } fprintf(stderr, "\n"); } - -signals: - void stringConsumed(const QString &text); }; //! [4] @@ -95,4 +106,3 @@ int main(int argc, char *argv[]) } //! [6] -#include "waitconditions.moc" |