本页内容

卫星信息

“卫星信息”示例通过“天空视图”、“表格视图”或“RSSI视图”显示可用的卫星,并展示用户的当前位置。该示例采用以下方式实现 Qt Positioning 和 Qt Quick实现。

本示例演示了 Qt Positioning QML API:

该示例还展示了如何将自定义的C++ 模型与来自QML 的自定义代理模型结合使用。

运行示例

您可以通过以下方式运行示例:

界面操作指南

该示例在三个不同的选项卡中显示卫星信息。数据取自SatelliteSource::satellitesInView 和SatelliteSource::satellitesInUse 的属性。

卫星视图和表格界面

“天空视图”标签页使用Azimuth 和Elevation attributes 显示卫星的相对位置。点击单个卫星对象会弹出一个包含satellite identifier 及其方位角和仰角的弹出窗口。

“表格视图”选项卡显示所有已检测到的卫星列表,并允许对列表进行排序和筛选。

带卫星信号条的RSSI视图

“RSSI 视图”选项卡通过signalStrength 属性显示视野内卫星的信号强度。条形图下方的数字代表各个satellite identifiers 的值。

“天空视图”和“RSSI 视图”选项卡还会显示当前的纬度和经度。它们使用PositionSource::position 属性来提取这些信息。

标签页顶部的“状态”块会显示当前模式或最近出现的错误。

“设置”菜单允许您切换应用程序的颜色模式并显示帮助信息。

该应用程序有三种不同的运行模式:

应用程序模式描述
运行中应用程序会持续向系统查询卫星和位置更新。当有新数据时,将显示相关信息。
已停止应用程序停止更新卫星和位置信息。
单次应用程序发出一次卫星和位置更新请求。

如果平台未提供卫星或位置信息,应用程序将自动切换至模拟模式。模拟模式使用包含预先记录的 NMEA 数据的NMEA 插件。

注意:Apple 未提供任何用于检索卫星信息的 API,因此在macOS 和iOS 上,卫星信息将始终来自预先记录的数据。这些 API 限制不会影响定位信息,因此当前位置仍可正确显示。

获取当前位置

当前位置是从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 视图的实现使用了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` 调用。例如,“卫星标识符”(Satellite Identifier)委托使用 `updateSelectedSystems() ` 槽来显示或隐藏属于特定卫星系统的卫星信息。同样,“卫星状态”(Satellite Status)委托使用 `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

源文件

示例项目 @ code.qt.io

另请参阅 所有 Qt 示例、Qt Positioning 示例以及Qt Quick 示例和教程。

© 2026 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.