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:
Anwendungsmodus | Beschreibung |
---|---|
Laufend | Die Anwendung fragt ständig das System nach Satelliten- und Positionsaktualisierungen ab. Sobald neue Daten verfügbar sind, werden diese angezeigt. |
Gestoppt | Die Anwendung stoppt die Aktualisierung der Satelliten- und Positionsdaten. |
Einzeln | Die 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
© 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.