Sur cette page

Graphique de dispersion simple

Utilisation de Scatter3D dans une application QML.

Simple Scatter Graph (graphique de dispersion simple) montre comment visualiser un graphique de dispersion simple à l'aide de Scatter3D et de QML.

Pour savoir comment interagir avec le graphique, voir cette page.

Pour savoir comment créer votre propre application Qt Quick, consultez l'aide Qt Creator.

Exécution de l'exemple

Pour exécuter l'exemple à partir de Qt CreatorOuvrez le mode Welcome et sélectionnez l'exemple à partir de Examples. Pour plus d'informations, voir Qt Creator: Tutorial : Construire et exécuter.

Mise en place de la présentation

Avant de plonger dans le code QML, main.cpp met en place l'application. Le fichier main.qml est lu à partir de la ressource (qrc:)

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

Ce fichier main.qml est le point de départ du code QML de l'application. Tout d'abord, importez tous les modules QML nécessaires :

import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import QtGraphs

Ensuite, créez un élément Data qui sera l'élément contenant les données du graphique.

Data {
    id: seriesData
}

Ensuite, créez deux éléments GraphsTheme qui définissent deux thèmes différents pour le graphique, un thème Qt Green et un thème Qt Neon Green.

GraphsTheme {
    id: themeQt
    theme: GraphsTheme.Theme.QtGreen
    labelFont.pointSize: 40
}

GraphsTheme {
    id: themeQtNeonGreen
    theme: GraphsTheme.Theme.QtGreenNeon
    colorScheme: GraphsTheme.ColorScheme.Dark
}

La présentation de cette application consistera en cinq boutons différents permettant d'activer et de désactiver différentes options visuelles pour le graphique, et bien sûr le graphique lui-même. Il existe de nombreuses façons d'organiser ces boutons, l'une d'entre elles étant d'avoir un site GridLayout contenant quatre boutons, le site Graph, et le cinquième bouton, tous apparaissant dans un site ColumnLayout.

ColumnLayout {
    id: mainLayout
    anchors.fill: parent
    anchors.margins: margin
    spacing: spacing

Le site GridLayout est réactif. Cela signifie que le nombre de colonnes utilisées dépend de la largeur de la fenêtre de l'application. Pour ce faire, on attribue à la propriété columns un opérateur ternaire, qui se résout en 1, 2 ou 4, en fonction de la largeur de la fenêtre.

GridLayout {
    Layout.fillWidth: true
    rowSpacing: spacing
    columnSpacing: spacing

    columns: mainView.width < mainView.buttonMinWidth * 2 + mainView.spacing + mainView.margin * 2 // width of 2 buttons
             ? 1
             : (mainView.width < mainView.buttonMinWidth * 4 + mainView.spacing * 3 + mainView.margin * 2 // width of 4 buttons
                ? 2
                : 4)

Dans ce site GridLayout, quatre sites RoundButtonsont instanciés. Un pour changer les ombres, un pour le lissage du maillage, un pour la position de la caméra et, enfin, un pour changer l'arrière-plan du graphique. Tous les boutons suivent la même structure. Plutôt que de redéfinir cette structure pour tous les boutons, un composant personnalisé peut être créé.

component CustomButton : RoundButton {
    id: buttonRoot

CustomButtom Ce composant prolonge le type RoundButton, mais y ajoute quelques éléments. Des propriétés telles que Layout.minimumWidth, Layout.FillWidth, radius et background sont définies. Elles définissent le style et la disposition du bouton.

property alias source: iconImage.source

Layout.minimumWidth: buttonMinWidth
Layout.fillWidth: true

radius: mainView.radius

background: Rectangle {
    radius: mainView.radius
    color: "white"
    border.color: "black"
}

Alors que contentItem définit le contenu du bouton, dans ce cas un type Row contenant une icône et du texte. L'icône est importée à l'aide d'un type Image et de la propriété source. Le texte est créé à l'aide d'un type Label et défini à l'aide de sa propriété text. Deux alliances sont créées pour ces deux propriétés en haut du composant personnalisé, ce qui leur permettra d'être définies lorsqu'une instance de CustomButton est créée.

contentItem: Row {
    id: content
    Image {
        id: iconImage
    }
    Label {
        text: buttonRoot.text
        horizontalAlignment: Text.AlignLeft
        anchors.verticalCenter: parent.verticalCenter
    }
}

Dans GridLayout, quatre CustomButtonsont créés. Trois propriétés doivent être définies, les deux alliances pour l'image de l'icône et le texte, ainsi que le signal onClicked.

CustomButton {
    id: shadowButton
    text: graph.shadowQuality === Graphs3D.ShadowQuality.None ?
              qsTr("Show Shadows") : qsTr("Hide Shadows")
    source: graph.shadowQuality === Graphs3D.ShadowQuality.None ?
                "qrc:/images/shadow.svg" : "qrc:/images/shadow_hide.svg"
    onClicked: {
        graph.shadowQuality = graph.shadowQuality === Graphs3D.ShadowQuality.None ?
                    Graphs3D.ShadowQuality.High :
                    Graphs3D.ShadowQuality.None
    }
}

Par exemple, le bouton "shadow" définit le signal onClicked pour activer ou désactiver l'ombre.

Configuration du graphique

L'élément suivant de la présentation est le graphique Graph, qui est défini dans son propre fichier QML Graph.qml, et qui est instancié comme suit :

Graph {
    id: graph
    Layout.fillWidth: true
    Layout.fillHeight: true
}

Si l'on regarde son implémentation dans Graph.qml, le graphique est de type Scatter3D, imbriqué dans un type Item.

Scatter3D {
    id: scatterGraph

Avant de définir les ensembles de données, certaines propriétés des axes sont configurées.

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"

Configuration des données

Le graphique montre trois ensembles de données, représentant les données fournies dans Data.qml. Les ensembles de données sont stockés dans des types ListModel

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

ListModel {
    id: dataModelTwo
    ListElement{ xPos: 2.25 ; yPos: 1.36 ; zPos: -1.3 }
    ...
    ListElement{ xPos: -3.4 ; yPos: 0.6 ; zPos: 0.9 }
}

ListModel {
    id: dataModelThree
    ListElement{ xPos: 8.0; yPos: -2.0; zPos: 4.0 }
    ...
    ListElement{ xPos: 5.66 ; yPos: -4.98 ; zPos: 3.72 }
}

et exposés aux autres fichiers à l'aide de property aliases

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

Avant d'utiliser ces alias, créez un type Scatter3DSeries contenant un élément ItemModelScatterDataProxy.

Scatter3DSeries {
    id: scatterSeries
    itemLabelFormat: "Series 1: X:@xLabel Y:@yLabel Z:@zLabel"

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

Ce proxy de données fait référence aux ensembles de données de Data.qml à l'aide de sa propriété itemModel. Les alias mentionnés ci-dessus sont accessibles par l'intermédiaire de id du type Data instancié dans main.qml, seriesData.

itemModel: seriesData.model

Répétez cette opération pour les deux autres ensembles de données.

Scatter3DSeries {
    id: scatterSeriesTwo
    ...
ItemModelScatterDataProxy {
    itemModel: seriesData.modelTwo
    ...
    }
}
Scatter3DSeries {
    id: scatterSeriesThree
    ...
ItemModelScatterDataProxy {
    itemModel: seriesData.modelThree
    ...
    }
}

Le diagramme de dispersion pointe désormais vers les trois ensembles de données.

Il ne reste plus qu'à ajouter le bouton restant, le theme button, à notre ColumnLayout. La seule différence avec ce bouton est qu'il est positionné sur le côté gauche de la présentation. Pour ce faire, il suffit de définir la propriété Layout.alignment comme étant Qt.AlignLeft et Layout.fillWidth comme étant false.

CustomButton {
    id: themeButton
    Layout.alignment: Qt.AlignLeft
    Layout.fillWidth: false

Exemple de contenu

Exemple de projet @ 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.