卫星信息
本示例展示了使用 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 公司的商标。所有其他商标均为其各自所有者的财产。