위성 정보

위성 정보 예제는 스카이 뷰, 테이블 뷰 또는 RSSI 뷰를 사용하여 사용 가능한 위성과 사용자의 현재 위치를 표시합니다. 이 예제는 Qt PositioningQt Quick.

이 예에서는 Qt Positioning QML API:

이 예에서는 사용자 정의 C++ 모델을 QML 의 사용자 정의 프록시 모델과 함께 사용하는 방법도 보여줍니다.

UI 개요

이 예에서는 위성 정보를 세 개의 서로 다른 탭에 표시합니다. 데이터는 SatelliteSource::satellitesInViewSatelliteSource::satellitesInUse 속성에서 가져옵니다.

스카이 뷰 탭에는 AzimuthElevation attributes 을 사용하여 상대 위성 위치가 표시됩니다. 개별 위성 개체를 클릭하면 satellite identifier, 방위각 및 고도가 포함된 팝업이 열립니다.

표 보기 탭에는 감지된 모든 위성의 목록이 표시되며, 목록에 정렬 및 필터링을 적용할 수 있습니다.

RSSI 보기 탭에는 signalStrength 속성을 사용하여 보이는 위성의 신호 세기가 표시됩니다. 막대 아래의 숫자는 개별 satellite identifiers 을 나타냅니다.

하늘 보기RSSI 보기 탭에는 현재 위도와 경도도 표시됩니다. PositionSource::position 속성을 사용하여 이 정보를 추출합니다.

탭 상단의 상태 블록에는 현재 모드 또는 마지막 오류가 표시됩니다.

설정 메뉴에서는 애플리케이션 색상 모드를 전환하고 도움말 정보를 표시할 수 있습니다.

애플리케이션은 세 가지 모드로 작동합니다:

애플리케이션 모드설명
실행 중애플리케이션이 위성 및 위치 업데이트를 위해 시스템에 지속적으로 쿼리합니다. 새 데이터를 사용할 수 있게 되면 해당 데이터가 표시됩니다.
중지됨애플리케이션이 위성 및 위치 정보 업데이트를 중지합니다.
단일애플리케이션이 위성 및 위치 업데이트를 한 번만 요청합니다.

플랫폼이 위성 또는 위치 정보를 제공하지 않으면 애플리케이션이 자동으로 시뮬레이션 모드로 전환됩니다. 시뮬레이션 모드는 미리 기록된 NMEA 데이터와 함께 NMEA 플러그인을 사용합니다.

참고: Apple은 위성 정보를 검색하기 위한 API를 제공하지 않으므로 macOSiOS 에서는 항상 사전 기록된 데이터에서 위성 정보를 가져옵니다. 이러한 API 제한은 위치 정보에는 영향을 미치지 않으므로 현재 위치가 올바르게 표시될 수 있습니다.

예제 실행하기

에서 예제를 실행하려면 Qt Creator에서 Welcome 모드를 열고 Examples 에서 예제를 선택합니다. 자세한 내용은 예제 빌드 및 실행하기를 참조하세요.

현재 위치 검색하기

현재 위치는 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 객체에서 검색됩니다. onSatellitesInViewChangedonSatellitesInUseChanged 핸들러는 각각 뷰에 있는 업데이트된 위성과 사용 중인 위성을 가져오는 데 사용됩니다. 이 예제에서는 데이터가 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++ 모델 사용

이 예제에서는 SatelliteModelSortFilterModel 이라는 두 개의 사용자 정의 모델을 사용합니다.

위성 모델

SatelliteModel 클래스는 QAbstractListModel 에서 파생되며 rowCount(), data() 및 roleNames() 메서드를 재구현하여 위성 정보를 표현합니다. QAbstractListModel 을 기본 클래스로 사용하면 QML ListViewRepeater 유형과 함께 모델을 쉽게 사용할 수 있습니다. 사용자 정의 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 에서 모두 호출할 수 있습니다. 예를 들어 위성 식별자 델리게이트는 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

예제 프로젝트 @ code.qt.io

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