Sensoren

Das Beispiel „Sensoren“ zeigt, wie zwei Anwendungen über UDP-Sockets mithilfe von Protobuf-Nachrichten miteinander kommunizieren können.

Das Beispiel „Sensoren“ besteht aus den folgenden Komponenten:

  • protobuf_sensors Bibliothek, die Sie mithilfe des Aufrufs ` qt_add_protobuf ` aus dem Protobuf-Schema generieren.
  • protobuf_sensor_emulator Anwendung, die ein einfaches Sensorverhalten emuliert.
  • protobuf_sensors_client Anwendung, die die Sensordaten aus dem UDP-Socket anzeigt.

Die Client-Anwendung bindet sich an den UDP-Port 65500 unter localhost und wartet auf Daten von der Emulator-Anwendung.

Fenster der Client-Konsole mit den Koordinaten für Breitengrad, Längengrad und Höhe sowie einem Feld für die Wettertemperatur

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

Screenshot einer Emulator-Konsolenanwendung zum Senden von Koordinaten, der Temperatur und einer Warnmeldung

Die Anwendungen nutzen die von der Bibliothek „ protobuf_sensors “ generierten Nachrichten zur Kommunikation. Die Bibliothek wird anhand des in den .proto-Dateien beschriebenen Protobuf-Schemas 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;
}

Die Meldungen werden mithilfe von ` QProtobufSerializer ` serialisiert, das Sie auf dem Client instanziieren:

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

Und im 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 „ QLineEdit “ vom String-Format in das für das jeweilige Nachrichtenfeld spezifische Format konvertiert, beispielsweise in den Typ „double“ für die Felder der Nachricht „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);
    });

Anschließend wird die Nachricht mit allen Feldern serialisiert und in die „Type-Length-Value“-Nachricht eingebettet:

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

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: Bevor Sie das Beispiel ausführen, stellen Sie sicher, dass Ihr Betriebssystem die Bindung an den UDP-Port 65500 sowie das Senden der Daten über UDP zulässt.

Beispielprojekt @ 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.