Sensoren

Das Sensors-Beispiel zeigt, wie zwei Anwendungen kommunizieren können, indem sie protobuf-Nachrichten über UDP-Sockets senden.

Das Sensors-Beispiel besteht aus den folgenden Komponenten:

  • protobuf_sensors Bibliothek, die Sie mit dem Aufruf qt_add_protobuf aus dem protobuf-Schema erzeugen.
  • protobuf_sensor_emulator Anwendung, die ein einfaches Sensorverhalten emuliert.
  • protobuf_sensors_client Anwendung, die die Sensordaten aus dem UDP-Socket anzeigt.

Die Client-Anwendung verbindet sich mit dem UDP-Port localhost 65500 und wartet auf Daten von der Emulator-Anwendung.

Verwenden Sie die Emulatoranwendung, um die Werte der Sensordaten zu ändern und die Daten an den UDP-Port des Clients zu senden.

Die Anwendungen verwenden die von der Bibliothek protobuf_sensors generierten Nachrichten zur Kommunikation. Die Bibliothek wird aus dem in .proto-Dateien beschriebenen Protobuf-Schema generiert.

qt_add_protobuf(protobuf_sensors
    PROTO_FILES
        sensors.proto
        tlv.proto
)

Die erste Datei beschreibt die Type-Length-Value-Nachricht, die die Sensordaten umschließt:

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

Die zweite .proto-Datei enthält eine Beschreibung der Sensormeldungen:

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

Nachrichten werden mit Hilfe von QProtobufSerializer serialisiert, die Sie im Client instanziieren:

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

Und der Emulator:

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

Nachdem Sie in der Emulatoranwendung auf die Schaltfläche Send geklickt haben, werden die Daten aus den Feldern von QLineEdit vom String-Format in das nachrichtenfeldspezifische Format konvertiert, z. B. doppelt für die Felder der Koordinatenmeldung:

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

Anschließend wird die Nachricht mit allen Feldern serialisiert und mit der Type-Length-Value-Nachricht verpackt:

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

Der Client wendet die umgekehrten Operationen auf die empfangenen Datagramme an. Zunächst wird die Type-Length-Value-Nachricht aus den Datagrammdaten deserialisiert:

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

Anschließend wird die Type-Length-Value-Nachricht in die Sensornachricht deserialisiert:

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

Schließlich wird sie konvertiert und dem Benutzer angezeigt:

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

Hinweis: Vergewissern Sie sich vor der Ausführung des Beispiels, dass Ihr Betriebssystem die Bindung an den UDP-Port 65500 und das Senden der Daten über UDP zulässt.

Beispielprojekt @ code.qt.io

© 2025 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.