Satelliten-Infos

Das Beispiel "Satelliteninfo" zeigt die verfügbaren Satelliten in der Himmelsansicht, der Tabellenansicht oder der RSSI-Ansicht sowie die aktuelle Position des Benutzers an. Es ist implementiert mit Qt Positioning und Qt Quick.

Dieses Beispiel demonstriert die Verwendung von Qt Positioning QML API:

Das Beispiel zeigt auch, wie man ein benutzerdefiniertes C++ -Modell zusammen mit einem benutzerdefinierten Proxy-Modell von QML verwendet.

UI-Übersicht

Das Beispiel zeigt Satelliteninformationen auf drei verschiedenen Registerkarten. Die Daten werden von den Eigenschaften SatelliteSource::satellitesInView und SatelliteSource::satellitesInUse übernommen.

Die Registerkarte " Himmelsansicht" zeigt die relativen Satellitenpositionen unter Verwendung der Azimuth und Elevation attributes . Wenn Sie auf ein einzelnes Satellitenobjekt klicken, öffnet sich ein Popup-Fenster mit dem satellite identifier, seinem Azimut und seiner Elevation.

Die Registerkarte Tabellenansicht zeigt die Liste aller erkannten Satelliten an und ermöglicht die Anwendung von Sortier- und Filterfunktionen auf die Liste.

Die Registerkarte RSSI-Ansicht zeigt die Signalstärke der Satelliten im Sichtfeld unter Verwendung der Eigenschaft signalStrength an. Die Zahlen unter den Balken stellen die einzelnen satellite identifiers dar.

Die Registerkarten Himmelsansicht und RSSI-Ansicht zeigen auch den aktuellen Breiten- und Längengrad an. Sie verwenden die Eigenschaft PositionSource::position, um diese Informationen zu extrahieren.

Der Statusblock oben auf den Registerkarten zeigt den aktuellen Modus oder den letzten Fehler an.

Über das Menü Einstellungen können Sie den Farbmodus der Anwendung ändern und die Hilfeinformationen anzeigen.

Die Anwendung arbeitet in drei verschiedenen Modi:

AnwendungsmodusBeschreibung
LaufendDie Anwendung fragt ständig das System nach Satelliten- und Positionsaktualisierungen ab. Sobald neue Daten verfügbar sind, werden diese angezeigt.
GestopptDie Anwendung stoppt die Aktualisierung der Satelliten- und Positionsdaten.
EinzelnDie Anwendung fordert eine einzelne Satelliten- und Positionsaktualisierung an.

Die Anwendung schaltet automatisch in einen Simulationsmodus, wenn die Plattform keine Satelliten- oder Positionsdaten bereitstellt. Der Simulationsmodus verwendet ein NMEA-Plugin mit voraufgezeichneten NMEA-Daten.

Hinweis: Apple stellt keine APIs zum Abrufen von Satelliteninformationen zur Verfügung, so dass auf macOS und iOS die Satelliteninformationen immer aus voraufgezeichneten Daten übernommen werden. Diese API-Einschränkungen haben keinen Einfluss auf die Positionsdaten, so dass die aktuelle Position korrekt angezeigt werden kann.

Ausführen des Beispiels

Zum Ausführen des Beispiels von Qt Creatorzu starten, öffnen Sie den Modus Welcome und wählen Sie das Beispiel aus Examples. Weitere Informationen finden Sie unter Erstellen und Ausführen eines Beispiels.

Abrufen der aktuellen Position

Die aktuelle Position wird aus dem PositionSource QML-Objekt abgerufen. Der onPositionChanged Handler wird verwendet, um Positionsaktualisierungen zu empfangen. Die String-Darstellungen von Breitengrad und Längengrad werden aus der Eigenschaft coordinate extrahiert.

PositionSource {
    id: positionSource
    name: root.simulation ? "nmea" : ""
    onPositionChanged: {
        let posData = position.coordinate.toString().split(", ")
        positionBox.latitudeString = posData[0]
        positionBox.longitudeString = posData[1]
    }
}

Abrufen von Satellitendaten

Ähnlich wie bei der Position werden auch die aktuellen Satelliteninformationen vom SatelliteSource QML-Objekt abgerufen. Die Handler onSatellitesInViewChanged und onSatellitesInUseChanged werden verwendet, um die aktualisierten Satelliten in der Ansicht bzw. die verwendeten Satelliten abzurufen. In diesem Beispiel werden die Daten dann an das Modell C++ weitergeleitet, das später in allen Ansichten verwendet wird.

SatelliteSource {
    id: satelliteSource
    name: root.simulation ? "nmea" : ""
    onSatellitesInViewChanged: root.satellitesModel.updateSatellitesInView(satellitesInView)
    onSatellitesInUseChanged: root.satellitesModel.updateSatellitesInUse(satellitesInUse)
}

Hinweis: Das Beispiel zeigt sowohl die QML Positioning API als auch die Integration des C++-Modells in QML. Aus diesem Grund werden die Satelliteninformationen zuerst in QML abgerufen, dann an C++ weitergeleitet und dann zurück an QML, um im Modell verwendet zu werden. In der Praxis sollte man, wenn die Anwendung komplexe C++ Modelle verwenden soll, in Betracht ziehen, direkt die Klasse QGeoSatelliteInfoSource von C++ zu verwenden.

Verwendung benutzerdefinierter C++-Modelle

In diesem Beispiel werden zwei benutzerdefinierte Modelle verwendet - SatelliteModel und SortFilterModel.

Satellitenmodell

Die Klasse SatelliteModel ist von QAbstractListModel abgeleitet und implementiert die Methoden rowCount(), data() und roleNames() neu, um die Satelliteninformationen darzustellen. Die Verwendung von QAbstractListModel als Basisklasse ermöglicht die einfache Verwendung des Modells mit den Typen QML ListView und Repeater. Eine benutzerdefinierte Eigenschaft size wird nur in der Registerkarte RSSI-Ansicht verwendet, um die Breite der Registerkartenleisten dynamisch zu berechnen.

class SatelliteModel : public QAbstractListModel
{
    Q_OBJECT
    Q_PROPERTY(int size READ rowCount NOTIFY sizeChanged)
    QML_ELEMENT
public:
    explicit SatelliteModel(QObject *parent = nullptr);

    int rowCount(const QModelIndex &parent = QModelIndex()) const override;
    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
    QHash<int, QByteArray> roleNames() const override;

public slots:
    void updateSatellitesInView(const QList<QGeoSatelliteInfo> &inView);
    void updateSatellitesInUse(const QList<QGeoSatelliteInfo> &inUse);

signals:
    void sizeChanged();
};

Die Methode roleNames() wird verwendet, um die Rollen des Modells auf die Eigenschaftsnamen abzubilden, die für den Zugriff auf die Modelldaten über QML verwendet werden können. Beispielsweise wird der Name id verwendet, um die Satellitenkennung zu extrahieren, und der Name rssi wird verwendet, um die Signalstärke zu erhalten.

QHash<int, QByteArray> SatelliteModel::roleNames() const
{
    return {
        {Roles::IdRole, "id"},
        {Roles::RssiRole, "rssi"},
        {Roles::AzimuthRole, "azimuth"},
        {Roles::ElevationRole, "elevation"},
        {Roles::SystemRole, "system"},
        {Roles::SystemIdRole, "systemId"},
        {Roles::InUseRole, "inUse"},
        {Roles::VisibleNameRole, "name"}
    };
}

Auf der Seite QML können wir diese Namen verwenden, um die tatsächlichen Werte zu erhalten. Die Implementierung von RSSI View verwendet beispielsweise die Rollennamen rssi, inUse und id, um die Balken zu zeichnen, die einzelne Satelliten darstellen:

Repeater {
    id: repeater
    model: root.satellitesModel
    delegate: Rectangle {
        required property var modelData
        height: rect.height
        width: view.singleWidth
        color: "transparent"
        SemiRoundedRectangle {
            anchors.bottom: satId.top
            width: parent.width
            height: (parent.height - satId.height)
                    * Math.min(parent.modelData.rssi, rect.maxVisibleLevel)
                    / rect.maxVisibleLevel
            color: parent.modelData.inUse ? root.inUseColor : root.inViewColor
        }
        Text {
            id: satId
            anchors.horizontalCenter: parent.horizontalCenter
            anchors.bottom: parent.bottom
            text: parent.modelData.id
            color: Theme.textSecondaryColor
            font.pixelSize: Theme.smallFontSize
            font.weight: Theme.fontLightWeight
        }
    }
}
Proxy-Modell

Die Klasse SortFilterModel wird verwendet, um eine benutzerdefinierte Sortierung und Filterung der auf der Registerkarte Tabellenansicht angezeigten Satellitenobjekte zu ermöglichen.

Das Modell ist von QSortFilterProxyModel abgeleitet und implementiert die Methoden filterAcceptsRow() und lessThan() neu, um Filterung und Sortierung zu ermöglichen. Das Modell stellt auch mehrere slots zur Verfügung, um das Filter- und Sortierverhalten einzustellen.

class SortFilterModel : public QSortFilterProxyModel
{
    Q_OBJECT
    QML_ELEMENT
public:
    explicit SortFilterModel(QObject *parent = nullptr);

public slots:
    void updateFilterString(const QString &str);
    void updateShowInView(bool show);
    void updateShowInUse(bool show);
    void updateSelectedSystems(int id, bool show);
    void updateSortRoles(int role, bool use);

protected:
    bool filterAcceptsRow(int row, const QModelIndex &parent) const override;
    bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
};

Diese Slots können sowohl von C++ als auch von QML aufgerufen werden. Der Delegat " Satellite Identifier" verwendet beispielsweise den Slot updateSelectedSystems(), um die Informationen über Satelliten, die zu bestimmten Satellitensystemen gehören, ein- oder auszublenden. Ebenso verwenden die Satellitenstatus-Delegierten die Slots updateShowInView() und updateShowInUse(), um die Satelliten mit einem bestimmten Status zu filtern.

Repeater {
    model: root.satelliteSystemModel
    delegate: CheckElement {
        required property var modelData
        text: modelData.name
        Layout.alignment: Qt.AlignRight
        onCheckedChanged: {
            root.sortFilterModel.updateSelectedSystems(modelData.id, checked)
        }
    }
}
    ...
CheckElement {
    text: qsTr("In View")
    Layout.alignment: Qt.AlignRight
    onCheckedChanged: root.sortFilterModel.updateShowInView(checked)
}
CheckElement {
    text: qsTr("In Use")
    Layout.alignment: Qt.AlignRight
    onCheckedChanged: root.sortFilterModel.updateShowInUse(checked)
}

QML-Modul-Registrierung

CMake-Erstellung

Für einen CMake-basierten Build müssen wir die folgende Datei zur CMakeLists.txt hinzufügen:

qt_add_qml_module(satelliteinfo
    URI SatelliteInformation
    VERSION 1.0
    SOURCES
        roles.h
        satellitemodel.cpp satellitemodel.h
        sortfiltermodel.cpp sortfiltermodel.h
    QML_FILES
        ApplicationScreen.qml
        Button.qml
        Header.qml
        HelpPopup.qml
        LegendBox.qml
        Main.qml
        RssiView.qml
        PageButton.qml
        PermissionsScreen.qml
        PositionBox.qml
        SatelliteView.qml
        SettingsView.qml
        SkyView.qml
        Theme.qml
        ViewSwitch.qml
    RESOURCES
        icons/checkbox.svg
        icons/checkbox_blank.svg
        icons/darkmode.svg
        icons/filter.svg
        icons/help.svg
        icons/lightmode.svg
        icons/place.svg
        icons/qtlogo_green.png
        icons/qtlogo_white.png
        icons/rssiview.svg
        icons/satellite_small.png
        icons/satellite1.png
        icons/satellite2.png
        icons/search.svg
        icons/settings.svg
        icons/skyview.svg
        icons/sort.svg
        icons/tableview.svg
)
qmake Build

Für einen qmake-Build müssen wir die Datei satelliteinfo.pro wie folgt ändern:

CONFIG += qmltypes
QML_IMPORT_NAME = SatelliteInformation
QML_IMPORT_MAJOR_VERSION = 1

qml_resources.files = \
    qmldir \
    ApplicationScreen.qml \
    Button.qml \
    Header.qml \
    HelpPopup.qml \
    LegendBox.qml \
    Main.qml \
    RssiView.qml \
    PageButton.qml \
    PermissionsScreen.qml \
    PositionBox.qml \
    SatelliteView.qml \
    SettingsView.qml \
    SkyView.qml \
    Theme.qml \
    ViewSwitch.qml

qml_resources.prefix = /qt/qml/SatelliteInformation

RESOURCES += qml_resources

icon_resources.files = \
    icons/checkbox.svg \
    icons/checkbox_blank.svg \
    icons/darkmode.svg \
    icons/filter.svg \
    icons/help.svg \
    icons/lightmode.svg \
    icons/place.svg \
    icons/qtlogo_green.png \
    icons/qtlogo_white.png \
    icons/rssiview.svg \
    icons/satellite_small.png \
    icons/satellite1.png \
    icons/satellite2.png \
    icons/search.svg \
    icons/settings.svg \
    icons/skyview.svg \
    icons/sort.svg \
    icons/tableview.svg

icon_resources.prefix = /qt/qml/SatelliteInformation

RESOURCES += icon_resources

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.