卫星信息
卫星信息示例使用天空视图、表格视图或 RSSI 视图显示可用卫星以及用户当前位置。该示例使用 Qt Positioning和 Qt Quick.
该示例演示了 Qt Positioning QML API:
该示例还展示了如何将自定义C++
模型与来自QML
的自定义代理模型结合使用。
用户界面概述
该示例在三个不同的选项卡中显示卫星信息。数据来自SatelliteSource::satellitesInView 和SatelliteSource::satellitesInUse 属性。
天空视图"选项卡使用Azimuth
和Elevation
attributes 显示卫星的相对位置。单击单个卫星对象会弹出satellite identifier 、方位角和仰角。
表格视图"选项卡显示所有检测到的卫星列表,并可对列表进行排序和过滤。
RSSI 视图选项卡使用signalStrength 属性显示视图中卫星的信号强度。条形图下方的数字代表单个satellite identifiers 。
天空视图和RSSI 视图选项卡还显示当前的经纬度。它们使用PositionSource::position 属性提取此信息。
选项卡顶部的状态块显示当前模式或上次错误。
设置菜单允许切换应用程序的颜色模式并显示帮助信息。
应用程序可在三种不同模式下运行:
应用程序模式 | 说明 |
---|---|
运行 | 应用程序持续查询系统的卫星和位置更新。当有新数据时,就会显示出来。 |
停止 | 应用程序停止更新卫星和位置信息。 |
单次 | 应用程序发出单次卫星和位置更新请求。 |
如果平台不提供卫星或位置信息,应用程序会自动切换到模拟模式。模拟模式使用带有预录NMEA数据的 NMEA插件。
注意: Apple 不提供任何用于检索卫星信息的 API,因此在macOS
和iOS
上,卫星信息将始终来自预先录制的数据。这些 API 限制不会影响定位信息,因此可以正确显示当前位置。
运行示例
运行示例 Qt Creator,打开Welcome 模式并从Examples 中选择示例。更多信息,请参阅Qt Creator: 教程:构建并运行。
检索当前位置
当前位置从PositionSource QML 对象中获取。onPositionChanged
处理程序用于接收位置更新。纬度和经度的字符串表示是从coordinate 属性中提取的。
PositionSource { id: positionSource name: root.simulation ? "nmea" : "" onPositionChanged: { let posData = position.coordinate.toString().split(", ") positionBox.latitudeString = posData[0] positionBox.longitudeString = posData[1] } }
检索卫星信息
与位置类似,当前卫星信息也是从SatelliteSource QML 对象中提取的。onSatellitesInViewChanged
和onSatellitesInUseChanged
处理程序分别用于获取视图中的最新卫星和使用中的卫星。在本例中,数据被转发到C++
模型,随后用于所有视图。
SatelliteSource { id: satelliteSource name: root.simulation ? "nmea" : "" onSatellitesInViewChanged: root.satellitesModel.updateSatellitesInView(satellitesInView) onSatellitesInUseChanged: root.satellitesModel.updateSatellitesInUse(satellitesInUse) }
注: 本例同时展示了 QML 定位 API 和 C++ 模型与 QML 的集成。这就是为什么卫星信息首先在QML
中检索,然后转发到C++
,再返回QML
在模型中使用。在实际应用中,如果应用程序要使用复杂的C++
模型,可考虑直接使用C++
中的QGeoSatelliteInfoSource 类。
使用自定义 C++ 模型
该示例使用了两个自定义模型 -SatelliteModel
和SortFilterModel
。
卫星模型
SatelliteModel
类派生自QAbstractListModel ,并重新实现了rowCount(),data() 和roleNames() 方法来表示卫星信息。使用QAbstractListModel 作为基类,可以方便地将该模型与QML
ListView 和Repeater 类型一起使用。自定义size
属性仅用于RSSI 视图选项卡,以动态计算选项卡条的宽度。
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(); };
roleNames()
方法用于将模型的角色映射到属性名称,这些名称可用于从QML
访问模型数据。例如,id
名称用于提取卫星标识符,rssi
名称用于获取信号强度。
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"} }; }
在QML
端,我们可以使用这些名称获取实际值。例如,RSSI View的实现使用rssi
、inUse
和id
角色名来绘制代表各个卫星的条形图:
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 } } }
代理模型
SortFilterModel
类用于对表视图选项卡中显示的卫星对象进行自定义排序和过滤。
该模型源自QSortFilterProxyModel ,并重新实现了filterAcceptsRow() 和lessThan() 方法,以提供筛选和排序功能。该模型还公开了几个slots
来调整过滤和排序行为。
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; };
这些槽可从C++
和QML
调用。例如,卫星标识符委托使用updateSelectedSystems()
插槽来显示或隐藏属于某些卫星系统的卫星信息。同样,卫星状态委托使用updateShowInView()
和updateShowInUse()
插槽过滤具有特定状态的卫星。
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 模块注册
CMake 构建
对于基于 CMake 的构建,我们需要在CMakeLists.txt
:
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 编译
对于 qmake 联编,我们需要按以下方式修改satelliteinfo.pro
文件:
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.