이 페이지에서

간단한 산점도

QML 애플리케이션에서 Scatter3D 사용하기.

'간단한 산점도'에서는 Scatter3D와 QML을 사용하여 간단한 산점도 시각화를 만드는 방법을 보여줍니다.

그래프와 상호 작용하는 방법에 대한 지침은 이 페이지를 참조하십시오.

새로운 Qt Quick 애플리케이션을 직접 만드는 방법에 대한 지침은 Qt Creator 도움말을 참조하십시오.

모양과 밀도가 서로 다른 세 점의 시계열 데이터를 나타내는 3D 산점도

예제 실행

다음에서 예제를 실행할 수 있습니다.

애플리케이션 기본 사항

QML 코드를 자세히 살펴보기 전에, main.cpp 애플리케이션을 먼저 확인해 보십시오.

이 애플리케이션은 UI에 'Quit' 버튼을 구현하고 있으므로, QQmlEngine::quit() 신호를 애플리케이션의 QWindow::close() 슬롯에 연결해야 합니다:

QObject::connect(viewer.engine(), &QQmlEngine::quit, &viewer, &QWindow::close);

배포 과정을 조금 더 간편하게 하려면, 애플리케이션의 모든 .qml 파일을 하나의 리소스 파일(qmlscatter.qrc)로 모아주세요:

<RCC>
    <qresource prefix="/">
        <file>qml/qmlscatter/Data.qml</file>
        <file>qml/qmlscatter/main.qml</file>
    </qresource>
</RCC>

이를 위해서는 main.qml 파일을 리소스(qrc:)에서 읽도록 설정해야 합니다:

viewer.setSource(QUrl("qrc:/qml/qmlscatter/main.qml"));

qmake 대신 cmake를 사용하는 경우, .qml 파일들은 CMakeLists.txt 내의 QML 모듈에 추가됩니다:

qt6_add_qml_module(qmlscatter
    URI Scatter
    VERSION 1.0
    NO_RESOURCE_TARGET_PATH
    QML_FILES
        qml/qmlscatter/Data.qml
        qml/qmlscatter/main.qml
)

마지막으로, 애플리케이션이 최대화된 창에서 실행되도록 설정합니다:

viewer.showMaximized();

그래프 설정

먼저, 필요한 모든 QML 모듈을 임포트합니다:

import QtQuick
import QtQuick.Controls
import QtDataVisualization

그런 다음 메인 ` Item `을 생성하고 이름을 ` mainView`으로 지정합니다:

Item {
    id: mainView

그런 다음, 메인 Item 내부에 또 다른 Item 를 추가하고 이름을 dataView 로 지정합니다. 이 항목은 Scatter3D 그래프를 담을 역할을 합니다. 이 항목을 부모 요소의 하단에 고정(anchor)시킵니다:

Item {
    id: dataView
    anchors.bottom: parent.bottom

다음으로, Scatter3D 그래프 자체를 추가합니다. dataView 내부에 추가하고 이름을 scatterGraph 로 지정합니다. dataView 전체를 채우도록 설정합니다:

Scatter3D {
    id: scatterGraph
    anchors.fill: parent

이제 그래프를 사용할 준비가 되었지만, 데이터는 없습니다. 또한 기본 축과 시각적 속성이 적용되어 있습니다.

다음으로, 먼저 scatterGraph 내부에 다음 내용을 추가하여 몇 가지 시각적 속성을 수정해 보겠습니다:

theme: themeQt
shadowQuality: AbstractGraph3D.ShadowQualityHigh
scene.activeCamera.cameraPreset: Camera3D.CameraPresetFront

사용자 정의 테마가 추가되었고, 그림자 품질이 변경되었으며, 카메라 위치가 조정되었습니다. 다른 시각적 속성은 문제가 없으므로 변경할 필요가 없습니다.

사용자 정의 테마는 미리 정의된 테마인 Theme3D.ThemeQt 을 기반으로 하지만, 이 테마의 글꼴이 변경되었습니다:

Theme3D {
    id: themeQt
    type: Theme3D.ThemeQt
    font.pointSize: 40
}

그런 다음 그래프에 데이터를 입력하기 시작합니다.

그래프에 데이터 추가하기

mainView 내에 ‘ Data ’ 항목을 생성하고 이름을 ‘ seriesData ’로 지정합니다:

Data {
    id: seriesData
}

이 ‘ seriesData ’ 항목에는 이 예제에서 사용되는 세 가지 시리즈 모두에 대한 데이터 모델이 포함되어 있습니다.

이 컴포넌트는 ‘ Data.qml ’ 내에 데이터를 보관하는 역할을 합니다. 이 컴포넌트의 메인 컴포넌트는 ‘ Item ’입니다.

메인 컴포넌트에서 데이터를 ‘ ListModel ’에 추가하고 이름을 ‘ dataModel ’로 지정합니다:

ListModel {
    id: dataModel
    ListElement{ xPos: -10.0; yPos: 5.0; zPos: -5.0 }
    ...

나머지 두 시리즈에도 이와 같은 구성 요소를 두 개 더 추가하고, 각각 ‘ dataModelTwo ’과 ‘ dataModelThree ’이라는 이름을 지정하세요.

그런 다음, main.qml 에서 사용할 수 있도록 데이터 모델을 노출시킵니다. 이를 위해 메인 데이터 컴포넌트에서 해당 모델들을 별칭으로 정의합니다:

property alias model: dataModel
property alias modelTwo: dataModelTwo
property alias modelThree: dataModelThree

이제 main.qml 에서 Data.qml 의 데이터를 scatterGraph 와 함께 사용할 수 있습니다. 먼저 Scatter3DSeries를 추가하고 이름을 ‘ scatterSeries ’로 지정하세요:

Scatter3DSeries {
    id: scatterSeries

그런 다음, 시리즈의 선택 레이블 형식을 설정합니다:

itemLabelFormat: "Series 1: X:@xLabel Y:@yLabel Z:@zLabel"

마지막으로, ItemModelScatterDataProxy에 첫 번째 시리즈의 데이터를 추가합니다. 프록시의 데이터로 itemModel 를 설정합니다:

ItemModelScatterDataProxy {
    itemModel: seriesData.model
    xPosRole: "xPos"
    yPosRole: "yPos"
    zPosRole: "zPos"
}

나머지 두 시리즈도 같은 방식으로 추가하되, 시리즈별 세부 사항을 약간 수정합니다:

Scatter3DSeries {
    id: scatterSeriesTwo
    itemLabelFormat: "Series 2: X:@xLabel Y:@yLabel Z:@zLabel"
    itemSize: 0.05
    mesh: Abstract3DSeries.MeshCube
    ...

그런 다음, ` scatterGraph ` 내의 기본 축 속성을 약간 수정합니다:

axisX.segmentCount: 3
axisX.subSegmentCount: 2
axisX.labelFormat: "%.2f"
axisZ.segmentCount: 2
axisZ.subSegmentCount: 2
axisZ.labelFormat: "%.2f"
axisY.segmentCount: 2
axisY.subSegmentCount: 2
axisY.labelFormat: "%.2f"

그 후, 그래프를 제어하기 위해 ` mainView `에 몇 개의 버튼을 추가합니다. 그중 하나를 예시로 보여드립니다:

Button {
    id: shadowToggle
    width: mainView.buttonWidth // Calculated elsewhere based on screen orientation
    anchors.left: parent.left
    anchors.top: parent.top
    anchors.margins: 5
    text: scatterGraph.shadowsSupported ? "Hide Shadows" : "Shadows not supported"
    enabled: scatterGraph.shadowsSupported
    onClicked: {
        if (scatterGraph.shadowQuality === AbstractGraph3D.ShadowQualityNone) {
            scatterGraph.shadowQuality = AbstractGraph3D.ShadowQualityHigh;
            text = "Hide Shadows";
        } else {
            scatterGraph.shadowQuality = AbstractGraph3D.ShadowQualityNone;
            text = "Show Shadows";
        }
    }
}

그런 다음, 상단에 버튼을 배치할 공간을 확보하기 위해 ` dataView `을 수정합니다:

Item {
    id: dataView
    anchors.bottom: parent.bottom
    width: parent.width
    // Adjust the space based on screen orientation:
    // If we're in portrait mode, we have 3 rows of buttons, otherwise they are all in one row.
    height: parent.height - (mainView.portraitMode ? shadowToggle.implicitHeight * 3 + 25
                                                   : shadowToggle.implicitHeight + 10)
    ...

이제 완료되었습니다!

예제 내용

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

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