Capteurs

L'exemple Sensors montre comment deux applications peuvent communiquer en envoyant des messages protobuf à l'aide de 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 application qui émule le comportement d'un capteur simple
  • protobuf_sensors_client application qui affiche les données du capteur à partir du socket UDP.

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

Utilisez l'application de l'émulateur pour modifier les valeurs des données du capteur et envoyez les données au port UDP du client.

Capture d'écran montrant une application console de l'émulateur permettant d'envoyer des coordonnées, la température météorologique 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 Type-Longueur-Valeur, qui contient les données du capteur :

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 du capteur :

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 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;
};

Après avoir cliqué sur le bouton Send dans l'application émulateur, les données des champs QLineEdit sont converties du format chaîne au format spécifique du champ du message, par exemple, double 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 avec tous les champs est ensuite sérialisé et enveloppé 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 aux 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::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-Longueur-Valeur est ensuite désérialisé dans le message du 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 par UDP.

Exemple de projet @ 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.