卫星信息
本示例展示了使用 Sky View、TableView 或 RSSI View 和用户当前位置查看可用的卫星。它使用 Qt 位置定位和 Qt Quick 实现。
此示例演示了 Qt 位置定位 QML API 的用法。
示例还展示了如何使用自定义 C++ 模型以及来自 QML 的自定义代理模型。
UI 概览
示例在三个不同的标签中展示了卫星信息。数据来源于 SatelliteSource::satellitesInView 和 SatelliteSource::satellitesInUse 属性。
天空视图 标签展示了使用 Azimuth 和 Elevation 属性的相对卫星位置。点击单个卫星对象将弹出一个包含卫星标识符、其方位角和仰角的弹出窗口。
表格视图 标签展示了所有检测到的卫星的列表,并允许对列表进行排序和筛选。
RSSI 视图 标签展示了所视卫星的信号强度,使用 signalStrength 属性。条形图下方数字代表单个卫星标识符。
天空视图 和 RSSI 视图 标签也显示了当前纬度和经度。它们使用 PositionSource::position 属性来提取此信息。
标签页上方的 状态 块显示了当前模式或最后错误。
设置 菜单允许切换应用程序颜色模式并显示帮助信息。
应用程序以三种不同的模式运行
应用程序模式 | 描述 |
---|---|
运行中 | 应用程序不断查询系统以获取卫星和位置更新。当有新数据可用时,它将进行显示。 |
停止 | 应用程序停止更新卫星和位置信息。 |
单次 | 应用程序发送单次卫星和位置更新请求。 |
如果平台不提供卫星或位置信息,应用程序将自动切换到模拟模式。模拟模式使用预记录的 NMEA 数据的 NMEA 插件。
注意: Apple 不提供任何获取卫星信息的 API,因此,在 macOS 和 iOS 上,卫星信息始终来自预记录的数据。这些 API 限制不会影响定位信息,因此可以正确显示当前位置。
运行示例
从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
属性来动态计算信号强度视图选项卡的标签栏宽度。
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
、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
© 2024 Qt 公司有限公司。此处包含的文档贡献属于各自的版权所有者。此处提供的文档是根据自由软件基金会发布的 GNU 自由文档许可证版本 1.3 的条款提供的。Qt 以及相应的标志是芬兰及/或其他国家 Qt 公司的商标。所有其他商标均为其各自所有者的财产。