Capteurs

L'exemple « Sensors » montre comment deux applications peuvent communiquer en envoyant des messages Protobuf via des sockets UDP.

L'exemple « Sensors » se compose des éléments suivants :

  • protobuf_sensors une bibliothèque que vous générez à partir du schéma Protobuf à l'aide de l'appel qt_add_protobuf.
  • protobuf_sensor_emulator une application qui émule le comportement d’un capteur simple.
  • protobuf_sensors_client une application qui affiche les données des capteurs provenant du socket UDP.

L'application cliente se connecte au port UDP 65500 de l'localhost et attend les données provenant de l'application émulatrice.

Fenêtre de la console client affichant les coordonnées de latitude, de longitude et d'altitude, ainsi qu'un champ indiquant la température

Utilisez l'application d'émulation pour modifier les valeurs des données du capteur et envoyer ces données vers le port UDP du client.

Capture d'écran présentant une application de console d'émulateur permettant d'envoyer des coordonnées, la température et un message d'avertissement

Les applications utilisent les messages générés par la bibliothèque protobuf_sensors pour communiquer. La bibliothèque est générée à partir du schéma Protobuf décrit dans les fichiers .proto.

qt_add_protobuf(protobuf_sensors
    PROTO_FILES
        sensors.proto
        tlv.proto
)

Le premier fichier décrit le message de type « Type-Length-Value », qui encapsule les données des capteurs :

package qt.examples.sensors.tlv;

enum MessageType {
    Coordinates = 0;
    Temperature = 1;
    WarningNotification = 2;
}

// Protobuf messages imply inline data size.
message TlvMessage {
    MessageType type = 1;
    bytes value = 2;
}

Le deuxième fichier .proto contient une description des messages des capteurs :

package qt.examples.sensors;

message Coordinates {
    double longitude = 1;
    double latitude = 2;
    double altitude = 3;
}

message Temperature {
    enum Unit {
        Farenheit = 0;
        Celsius = 1;
    }
    sint32 value = 1;
    Unit units = 2;
}

message WarningNotification {
    string text = 1;
}

Les messages sont sérialisés à l'aide de l'QProtobufSerializer, que vous instanciez dans le client :

class SensorClient : public QObject
{
    Q_OBJECT
...
private:
    QUdpSocket m_client;
    QProtobufSerializer m_serializer;
};

Et l’émulateur :

class SensorEmulator : public QObject
{
    Q_OBJECT
...
    QUdpSocket m_socket;
    QProtobufSerializer m_serializer;
};

Lorsque vous cliquez sur le bouton « Send » dans l’application d’émulation, les données des champs « QLineEdit » sont converties du format chaîne de caractères vers le format spécifique au champ du message. Par exemple, le type «double» est utilisé pour les champs du message «Coordinates» :

    QObject::connect(ui->sendCoordinates, &QPushButton::clicked, this, [this]() {
        qt::examples::sensors::Coordinates coord;
        coord.setLatitude(ui->latitudeValue->text().toDouble());
        coord.setLongitude(ui->longitudeValue->text().toDouble());
        coord.setAltitude(ui->altitudeValue->text().toDouble());
        emit coordinatesUpdated(coord);
    });

Le message contenant tous les champs est ensuite sérialisé et encapsulé dans le message « Type-Length-Value » :

    Q_ASSERT(serializer != nullptr);
    tlv::TlvMessage msg;
    msg.setType(type);
    msg.setValue(data);
    return msg.serialize(serializer);

Le client applique les opérations inverses sur les datagrammes reçus. Tout d’abord, le message « Type-Length-Value » est désérialisé à partir des données du datagramme :

       const auto datagram = m_client.receiveDatagram();
        qt::examples::Qt Sensors::tlv::TlvMessage msg;
        msg.deserialize(&m_serializer, datagram.data());
       if (m_serializer.lastError()
                != QAbstractProtobufSerializer::Error::None) {
            qWarning().nospace() << "Unable to deserialize datagram ("
                      << qToUnderlying(m_serializer.lastError()) << ")"
                       << m_serializer.lastErrorString();
            continue;
        }

Le message Type-Length-Value est ensuite désérialisé en message de capteur :

            qt::examples::sensors::Coordinates coord;
            coord.deserialize(&m_serializer, msg.value());
            emit coordinatesUpdated(coord);
            break;

Enfin, il est converti et affiché à l’utilisateur :

    ui->latitudeValue->setText(QString::number(coord.latitude(), 'f', 7));
    ui->longitudeValue->setText(QString::number(coord.longitude(), 'f', 7));
    ui->altitudeValue->setText(QString::number(coord.altitude(), 'f', 7));

Remarque : avant d'exécuter l'exemple, assurez-vous que votre système d'exploitation autorise la liaison sur le port UDP 65500 et l'envoi de données via UDP.

Exemple de projet sur code.qt.io

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.