Sur cette page

Tableau de bord des éoliennes

Un tableau de bord d’éolienne avec des graphiques en 2D et en 3D.

L'exemple « Tableau de bord d'éolienne » montre comment utiliser des graphiques en 2D et en 3D dans une application simulant une situation réelle.

Tableau de bord d'éolienne avec panneau d'état, graphiques de puissance et d'énergie, et visualisations en 3D

Exécution de l'exemple

Vous pouvez exécuter l'exemple à partir de :

Présentation de l’application

Cet exemple présente un tableau de bord de surveillance d’éoliennes, appelé « Aerospace Hub », qui affiche des données simulées provenant d’un parc éolien fictif. Divers types de graphiques sont utilisés pour visualiser différents types de données. Par exemple, un graphique 2D avec une série spline illustre la production d’énergie horaire, tandis qu’une série de surface associée représente l’énergie cumulée sur la même période. Plusieurs vues de données sont disponibles, permettant aux utilisateurs d’explorer et d’analyser les informations sous différents angles.

L’interface principale comporte une barre d’outils de paramètres à gauche. Selon le mode sélectionné, la mise en page peut inclure un volet d’état, un tableau de bord composé de petits graphiques, un grand graphique principal ou un panneau de paramètres détaillés – soit individuellement, soit en combinaison. Cette conception flexible permet aux utilisateurs de personnaliser leur vue et de se concentrer sur les données les plus pertinentes pour leur analyse en cours.

Vue « Tableau de bord »

La vue « Tableau de bord » présente l’état actuel du système à côté d’un volet défilable affichant des aperçus miniatures des différents graphiques. Jusqu’à quatre graphiques sont affichés simultanément, ce qui permet aux utilisateurs de parcourir facilement les six visualisations disponibles et d’évaluer rapidement les indicateurs de performance clés d’un seul coup d’œil.

Vue du tableau de bord avec l'état des turbines et quatre aperçus graphiques

Vue détaillée

La vue détaillée, accessible en sélectionnant un graphique miniature depuis le tableau de bord, permet aux utilisateurs d’examiner la visualisation choisie de manière plus approfondie et à plus grande échelle. Selon le type de graphique, les utilisateurs peuvent zoomer, effectuer un panoramique ou faire pivoter la vue pour explorer les données de manière interactive. De plus, il est possible de survoler ou de cliquer sur des points de données individuels pour afficher des informations plus détaillées sur l’élément qui les intéresse.

Vue détaillée avec l'état de la turbine et le graphique de la puissance produite

Vue des paramètres

La vue des paramètres, accessible en cliquant soit sur le bouton des paramètres dans la barre d'outils, soit sur un graphique miniature, permet aux utilisateurs d'ajuster le thème visuel des graphiques et de modifier les paramètres spécifiques à chaque type de graphique. Certaines configurations persistent après la fermeture de la vue des paramètres, tandis que d'autres ne s'appliquent qu'à la vue actuelle, offrant ainsi une grande flexibilité pour les ajustements temporaires comme permanents.

Fenêtre des paramètres avec histogramme et commandes de personnalisation des graphiques

Simulation des données

Toutes les données des graphiques sont générées par une hiérarchie de classes de simulateurs implémentées en C++. La classe de base, ` DataSimulator`, génère des valeurs aléatoires dans une plage configurable comprise entre ` min ` et ` max `. La propriété ` order ` détermine si la séquence est de type ` Ascending`, ` Descending` ou ` NotSorted`, et la propriété ` deviation ` limite l’écart maximal entre chaque valeur et la précédente. Lorsque la propriété ` live ` est définie sur ` true`, les données sont automatiquement mises à jour à l’intervalle spécifié par ` updatePeriod`. Les mises à jour s’exécutent sur un thread d’arrière-plan dédié, simulant ainsi une véritable source de données.

Chaque sous-classe est un élément QML destiné à un type de série spécifique :

  • LineSimulator — remplit QSplineSeries avec les valeurs générées.
  • BarSimulator — remplit QBarSeries, en regroupant les valeurs en ensembles de barres selon la propriété numberOfCategory.
  • PieSimulator — remplit l’ QPieSeries, en créant une tranche par valeur générée.
  • Data3DSimulator — alimente une instance de ` SimulatedDataModel ` (QAbstractListModel) utilisée par les types de graphiques 3D. Les propriétés ` numberOfRows ` et ` numberOfColumns ` définissent les dimensions de la grille des données.

Détails d’implémentation

Tout dans l’application a été conçu de manière modulaire. La vue principale, qui correspond au fichier Main.qml, est une classe ApplicationWindow qui instancie les simulateurs de données pour chaque graphique, ainsi que le Item racine contenant tous les éléments de l’interface utilisateur.

L’ FontLoader est utilisé pour appliquer une police globale à l’ensemble de l’interface utilisateur.

ApplicationWindow {
    ...

    FontLoader { ... }
    font.family: interFont.name

    // Data simulators
    PieSimulator {
        id: piesim
        ...
    }

    BarSimulator {
        id: barsim
        ...
    }

    LineSimulator {
        id: linesim
        ...
    }

    Data3DSimulator {
        id: barDataSimulator
        ...
    }

    Data3DSimulator {
        id: scatterDataSimulator
        ...
    }

    Data3DSimulator {
        id: surfaceDataSimulator
        ...
    }

    // Root item
    Item {...}
}

L’élément racine contient les graphiques d’arrière-plan et un Layout gérant le placement de chaque élément de l’interface utilisateur dans la vue :

// Background image
Image {
    anchors.fill: parent
    source: root.state === "ShowSettings" ? "images/settings-bg.png"
                                          : "images/dashboard-bg.png"
    fillMode: Image.PreserveAspectCrop
}

// Everything except background image
ColumnLayout {
    anchors.fill: parent
    ...

La plupart des éléments ont été extraits du fichier ` Main.qml ` lui-même pour être placés dans leurs propres composants QML destinés à être utilisés dans les mises en page, comme le ` ToolBarItem ` dans l’extrait ci-dessous :

// Vertical toolbar
ToolBarItem {
    Layout.preferredWidth: GlobalSettings.toolbarwidth
    Layout.fillHeight: true
}

// Everything except vertical toolbar, header, and background image
ColumnLayout {
    id: maincontentview
    Layout.fillWidth: true
    Layout.fillHeight: true
    ...

Les transitions entre les différentes vues sont gérées à l'aide d'states et d'transitions:

states: [
    State {
        name: "ShowDashboard"
    },
    State {
        name: "ShowSettings"
        PropertyChanges {
            maincontent.opacity: 0
            settingscontent.opacity: 1
        }
        PropertyChanges {
            viewtextdesc.text: "/  Settings"
        }
    },
    ...
// Use transitions to bring the selected view to the front
transitions: [
    Transition {
        NumberAnimation {
            properties: "opacity"
            easing.type: Easing.InOutCubic
            duration: 1000
        }
    }
]
Tableau de bord

Le tableau de bord fait partie du contenu principal ; il s’agit d’un autre élément « RowLayout » au sein de la hiérarchie « Layout » :

// Main content
RowLayout {
    id: maincontent
    Layout.fillWidth: true
    Layout.fillHeight: true
    ...

Il se compose d’un volet d’état et d’un volet de tableau de bord :

// Status area; turbine image, notification, status texts, and turbine name
StatusPane {
    id: statuspane
    Layout.preferredWidth: GlobalSettings.statusimagewidth
    Layout.fillHeight: true
}

// Scrollable dashboard graph area, shown when in ShowDashboard state
DashboardPane {
    id: dashboardpane
    contentheight: statuspane.height * 1.5
    Layout.preferredWidth: GlobalSettings.dashboardwidth
    Layout.fillHeight: true
}
Volet d’état

Le volet d’état est lui aussi composé d’éléments plus petits, implémentés dans leurs propres composants QML :

// Masking the turbine image of the background image
ImageItem {
    anchors.fill: parent
}

// Notification
NotificationItem {
    anchors.top: turbineimage.top
    anchors.horizontalCenter: turbineimage.horizontalCenter
    anchors.topMargin: GlobalSettings.doublespacing
    width: turbineimage.width / 1.25
}

// Status
StatusItem {
    anchors.centerIn: turbineimage
    width: turbineimage.width / 1.5
    height: turbineimage.width / 1.75
}

// Turbine name
Label {
    ...

Leur implémentation n'étant pas pertinente, cette partie sera ignorée.

Volet Tableau de bord

Le tableau de bord est l'élément qui contient les six petits aperçus de graphiques. Seuls quatre d'entre eux sont visibles à la fois ; ils doivent donc être placés à l'intérieur d'un élément pouvant faire l'objet d'un défilement. Dans ce cas précis, cela est réalisé à l'aide d'un « Flickable », qui contient un « GridLayout » :

Flickable {
    property alias contentheight: content.height

    clip: true

    contentHeight: contentheight

    boundsBehavior: Flickable.StopAtBounds
    interactive: true
    visible: opacity > 0.5

    Item {
        id: content
        width: parent.width

        GridLayout {
            id: grid
            columns: 2
    ...

Les aperçus de graphiques sont ajoutés à l’intérieur de la mise en page en grille et, comme la plupart des autres éléments, ils ont été implémentés dans leurs propres éléments :

// Graph 1: Power output over time
SmallGraphItem {
    Layout.fillWidth: true
    Layout.fillHeight: true
    state: "Area2D"
    linesimulator: linesim
}

// Graph 2: Energy production x Turbine
SmallGraphItem {
    Layout.fillWidth: true
    Layout.fillHeight: true
    state: "Bar2D"
    barsimulator: barsim
}
...

L’élément ` SmallGraphItem ` est un élément générique qui contient tous les différents types de graphiques, et le type requis lui est fourni sous la forme d’un ` state`.

SmallGraphItem comporte :

  • Un élément d’en-tête
  • Une instance de chaque type de graphique, dont la visibilité est définie par défaut sur « false » à l’aide d’un déclencheur d’opacité
  • Un rectangle permettant d’assombrir l’aperçu
  • Une zone de souris pour gérer le survol et les clics de souris sur l’aperçu
Pie2DGraph {
    id: pie2d
    anchors.topMargin: header.height + GlobalSettings.defaultspacing
    anchors.rightMargin: GlobalSettings.defaultspacing
    anchors.fill: parent
    opacity: 0
    piesimulator: smallgraph.piesimulator
}

Bar3DGraph {
    id: bar3d
    anchors.topMargin: header.height + GlobalSettings.defaultspacing
    anchors.bottomMargin: GlobalSettings.defaultspacing
    anchors.fill: parent
    opacity: 0
    cameraZoomLevel: GlobalSettings.defaultzoom
    cameraPreset: GlobalSettings.defaultpreset
}
...

Les opacités sont utilisées pour les animations de transition, c’est pourquoi elles sont définies par défaut sur 0 dans les aperçus. Lorsque l’opacité est animée au-delà de 0,5, le graphique d’aperçu lui-même devient visible :

Bars3D {
    id: graph
    visible: opacity > 0.5
    ...
Détails

La section « Détails » fait également partie du contenu principal, utilisant la même structure « RowLayout » au sein de la hiérarchie « Layout ». Elle se compose du même volet d’état que le tableau de bord, ainsi que d’un volet de détails :

// Details graph, shown when in correct state
BigGraphItem {
    id: detailspane
    Layout.preferredWidth: GlobalSettings.dashboardwidth
    Layout.fillHeight: true
    state: root.state
    radius: GlobalSettings.defaultradius
    piesimulator: piesim
    barsimulator: barsim
    linesimulator: linesim
    detailsview: true
}

Le volet « Détails », BigGraphItem, est similaire à l’ SmallGraphItem en ce sens qu’il contient également une instance de chaque graphique, en plus d’autres éléments :

// Graphs
Area2DGraph {
    id: area2dbig
    Layout.fillWidth: true
    Layout.fillHeight: true
    Layout.margins: GlobalSettings.defaultmargin
    opacity: 0
    panStyle: GraphsView.PanStyle.Drag
    zoomStyle: GraphsView.ZoomStyle.Center
    linesimulator: biggraph.linesimulator
    onVisibleChanged: {
        if (visible)
            biggraph.activegraph = area2dbig
    }
}

Bar2DGraph {
    id: bar2dbig
    Layout.fillWidth: true
    Layout.fillHeight: true
    Layout.margins: GlobalSettings.defaultmargin
    opacity: 0
    panStyle: GraphsView.PanStyle.Drag
    zoomStyle: GraphsView.ZoomStyle.Center
    barsimulator: biggraph.barsimulator
    onVisibleChanged: {
        if (visible)
            biggraph.activegraph = bar2dbig
    }
}
...

Parmi les autres éléments figurent une liste déroulante permettant de sélectionner le type de graphique, des boutons de commande pour la rotation, le panoramique et le zoom (selon le type de graphique) ainsi qu’une info-bulle pour les boutons. À l’instar de SmallGraphItem, le type de graphique affiché est déterminé en fonction de l’état.

Paramètres

Les paramètres ont été déplacés hors de la vue de contenu principale Layout, car ils n’utilisent aucun élément des vues Tableau de bord ou Détails:

// Settings
SettingsItem {
    id: settingscontent
    anchors.fill: parent
    ...

La vue « Paramètres » contient un autre BigGraphItem permettant d’afficher le graphique, ainsi qu’un volet de paramètres permettant de régler soit les propriétés d’ GraphsTheme, soit certaines propriétés spécifiques au type de graphique sélectionné.

// Graph detail
BigGraphItem {
    id: settingsgraph
    width: GlobalSettings.settingsgraphwidth
    anchors.top: parent.top
    anchors.bottom: parent.bottom
    anchors.topMargin: GlobalSettings.graphdetailmargin
    radius: GlobalSettings.defaultradius
    opacity: parent.opacity
    piesimulator: settingsitem.piesimulator
    barsimulator: settingsitem.barsimulator
    linesimulator: settingsitem.linesimulator
}

// Settings pane
Loader {
    active: settingsitem.visible
    asynchronous: true
    anchors.left: settingsgraph.right
    anchors.right: parent.right
    anchors.top: parent.top
    anchors.bottom: parent.bottom
    anchors.leftMargin: GlobalSettings.doublespacing

    sourceComponent: Item {
        StackLayout {
            id: settingspane
            anchors.fill: parent
    ...
Thème global

Les paramètres de l’onglet « General Settings » s’appliquent à tous les graphiques de l’application. Un GraphsTheme global a été implémenté sous la forme d’un Singleton dans GlobalSettings.qml:

pragma Singleton
...
QtObject {
    id: global
    ...
// Common graph theme
property var theme: GraphsTheme {
    plotAreaBackgroundVisible: false
    backgroundVisible: false
    colorScheme: GraphsTheme.ColorScheme.Dark
    theme: GraphsTheme.Theme.BlueSeries
    labelTextColor: "#AEAEAE"
    labelBackgroundVisible: true
    labelFont.pointSize: global.fontsize28px
    grid.mainColor: "#AEAEAE"
    grid.mainWidth: 1
    baseGradients: [ global.customgradient ]
}

Ce thème global partagé est défini comme thème pour chaque graphique :

theme: GlobalSettings.theme

En tant que singleton, l’ GlobalSettings.qml doit également être marqué comme tel dans l’ CMakeLists.txt pour pouvoir être utilisé dans l’application :

set_source_files_properties(qml/GlobalSettings.qml
    PROPERTIES QT_QML_SINGLETON_TYPE TRUE)
Paramètres du graphique

Les paramètres de l'onglet « Graph Settings » (Paramètres du graphique) n'affectent que le graphique actuellement sélectionné. Ces paramètres ne modifient pas le thème global, mais uniquement les séries du graphique actif.

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.