Auf dieser Seite

Windkraftanlagen-Dashboard

Ein Windkraftanlagen-Dashboard mit 2D- und 3D-Diagrammen.

Das Beispiel „Windkraftanlagen-Dashboard“ veranschaulicht, wie sowohl 2D- als auch 3D-Diagramme in einer simulierten realitätsnahen Anwendung verwendet werden können.

Windkraftanlagen-Dashboard mit Statusanzeige, Leistungs- und Energiediagrammen sowie 3D-Visualisierungen

Ausführen des Beispiels

Sie können das Beispiel wie folgt ausführen:

Übersicht über die Anwendung

Das Beispiel zeigt ein Dashboard zur Überwachung von Windkraftanlagen, das als „Aerospace Hub“ bezeichnet wird und simulierte Daten eines fiktiven Windparks anzeigt. Zur Visualisierung verschiedener Datentypen kommen unterschiedliche Diagrammtypen zum Einsatz. So veranschaulicht beispielsweise ein 2D-Diagramm mit einer Spline-Reihe die stündliche Leistungsabgabe, während eine begleitende Flächenreihe die kumulierte Leistung über denselben Zeitraum darstellt. Es stehen mehrere Datenansichten zur Verfügung, sodass Benutzer die Informationen aus verschiedenen Perspektiven untersuchen und analysieren können.

Die Hauptoberfläche verfügt links über eine Symbolleiste mit Einstellungen. Je nach ausgewähltem Modus kann das Layout einen Statusbereich, ein Dashboard mit kleineren Diagrammen, ein großes Hauptdiagramm oder ein detailliertes Einstellungsfeld enthalten – entweder einzeln oder in Kombination. Dieses flexible Design ermöglicht es Benutzern, ihre Ansicht anzupassen und sich auf die für ihre aktuelle Analyse relevantesten Daten zu konzentrieren.

Dashboard-Ansicht

Die Dashboard-Ansicht zeigt den aktuellen Systemstatus neben einem scrollbaren Bereich an, in dem Miniaturansichten der verschiedenen Diagramme angezeigt werden. Es werden bis zu vier Diagramme gleichzeitig dargestellt, sodass Nutzer bequem durch alle sechs verfügbaren Visualisierungen blättern und wichtige Leistungskennzahlen auf einen Blick schnell beurteilen können.

Dashboard-Ansicht mit Turbinenstatus und vier Diagramm-Vorschauen

Detailansicht

Die Detailansicht, die durch Auswahl eines Miniaturdiagramms aus dem Dashboard aufgerufen wird, ermöglicht es den Benutzern, die ausgewählte Visualisierung eingehender und in größerem Maßstab zu untersuchen. Je nach Diagrammtyp können Benutzer die Ansicht zoomen, verschieben oder drehen, um die Daten interaktiv zu erkunden. Darüber hinaus können einzelne Datenpunkte mit der Maus überfahren oder angeklickt werden, um detailliertere Informationen zu dem jeweiligen Element von Interesse anzuzeigen.

Detailansicht mit Turbinenstatus und Balkendiagramm zur Leistungsabgabe

Einstellungsansicht

Die Einstellungsansicht, die durch Klicken auf die Schaltfläche „Einstellungen“ in der Symbolleiste oder in einem Miniaturdiagramm aufgerufen wird, ermöglicht es Benutzern, das visuelle Design der Diagramme anzupassen und die für den jeweiligen Diagrammtyp spezifischen Einstellungen zu ändern. Bestimmte Konfigurationen bleiben auch nach dem Verlassen der Einstellungsansicht erhalten, während andere nur innerhalb der aktuellen Ansicht gelten, was Flexibilität sowohl für vorübergehende als auch für dauerhafte Anpassungen bietet.

Einstellungsansicht mit Balkendiagramm und Steuerelementen zur Anpassung des Diagramms

Datensimulation

Alle Diagrammdaten werden durch eine Hierarchie von Simulator-Klassen erzeugt, die in C++ implementiert sind. Die Basisklasse „ DataSimulator “ generiert Zufallswerte innerhalb eines konfigurierbaren Bereichs von „ min “ bis „ max “. Die Eigenschaft „ order “ steuert, ob die Sequenz „ Ascending “, „ Descending “ oder „ NotSorted “ ist, und die Eigenschaft „ deviation “ begrenzt, wie stark sich jeder Wert vom vorherigen unterscheiden darf. Wenn „ live “ auf „ true “ gesetzt ist, werden die Daten automatisch in dem durch „ updatePeriod “ festgelegten Intervall aktualisiert. Die Aktualisierungen laufen in einem eigenen Hintergrund-Thread und simulieren so eine echte Datenquelle.

Jede Unterklasse ist ein QML-Element, das auf einen bestimmten Serientyp ausgerichtet ist:

  • LineSimulator — füllt ` QSplineSeries ` mit den generierten Werten.
  • BarSimulator — füllt „ QBarSeries “ und gruppiert die Werte entsprechend der Eigenschaft „ numberOfCategory “ in Balkensätze.
  • PieSimulator — füllt „ QPieSeries “ und erstellt dabei einen Ausschnitt pro generiertem Wert.
  • Data3DSimulator — speist ein „ SimulatedDataModel “ (QAbstractListModel), das von den 3D-Diagrammtypen verwendet wird. Die Eigenschaften „ numberOfRows “ und „ numberOfColumns “ definieren die Rasterabmessungen der Daten.

Implementierungsdetails

Die gesamte Anwendung wurde modular aufgebaut. Die Hauptansicht, bei der es sich um die Datei „ Main.qml “ handelt, ist ein „ ApplicationWindow “, der die Datensimulatoren für jedes Diagramm sowie den Stamm-„ Item “ instanziiert, der alle UI-Elemente enthält.

Die ` FontLoader ` wird verwendet, um eine globale Schriftart für die gesamte Benutzeroberfläche festzulegen.

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 {...}
}

Das Root-Element enthält die Hintergrundgrafiken und ein „ Layout “, das die Platzierung der einzelnen UI-Elemente in der Ansicht verwaltet:

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

Die meisten Elemente wurden aus der „ Main.qml “-Datei selbst herausgelöst und in eigene QML-Komponenten überführt, die in den Layouts verwendet werden, wie beispielsweise das „ ToolBarItem “ im folgenden Ausschnitt:

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

Übergänge zwischen verschiedenen Ansichten werden mithilfe von „ states “ und „ transitions “ abgewickelt:

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
        }
    }
]
Dashboard

Das Dashboard ist Teil des Hauptinhalts und ein weiteres „ RowLayout “ innerhalb der „ Layout “-Hierarchie:

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

Es besteht aus einem Statusbereich und einem Dashboard-Bereich:

// 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
}
Statusbereich

Auch der Statusbereich setzt sich aus kleineren Elementen zusammen, die in eigenen QML-Komponenten implementiert sind:

// 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 {
    ...

Die Implementierung dieser Elemente ist nicht relevant, daher wird dieser Teil übersprungen.

Dashboard-Bereich

Das Dashboard ist das Element, das die sechs kleinen Diagrammvorschauen enthält. Da jeweils nur vier davon sichtbar sind, müssen sie in ein Element eingefügt werden, das gescrollt werden kann. In diesem Fall geschieht dies mithilfe eines „ Flickable “, das ein „ GridLayout “ enthält:

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

Die Diagrammvorschauen werden innerhalb des Rasterlayouts eingefügt und sind, wie die meisten anderen Elemente, in eigenen Elementen implementiert:

// 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
}
...

Das Element „ SmallGraphItem “ ist ein generisches Element, das alle verschiedenen Diagrammtypen enthält, und der gewünschte Typ wird ihm als „ state “ übergeben.

„SmallGraphItem“ verfügt über:

  • Ein Header-Element
  • Eine Instanz jedes Diagrammtyps, deren Sichtbarkeit standardmäßig mithilfe eines Opazitäts-Triggers auf „false“ gesetzt ist
  • Ein Rechteck zum Abdunkeln der Vorschau
  • Einen Mausbereich zur Verarbeitung von Hover- und Mausklicks auf der Vorschau
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
}
...

Opazitäten werden für Übergangsanimationen verwendet, weshalb sie in den Vorschauen standardmäßig auf 0 gesetzt sind. Wenn die Opazität über 0,5 animiert wird, wird das Vorschau-Diagramm selbst als sichtbar markiert:

Bars3D {
    id: graph
    visible: opacity > 0.5
    ...
Details

„Details“ ist ebenfalls Teil des Hauptinhalts und nutzt denselben „ RowLayout “ innerhalb der „ Layout “-Hierarchie. Es besteht aus demselben Statusbereich wie das Dashboard sowie einem Detailbereich:

// 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
}

Der Detailbereich, „ BigGraphItem “, ähnelt dem „ SmallGraphItem “ insofern, als er neben anderen Elementen ebenfalls eine Instanz jedes Diagramms enthält:

// 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
    }
}
...

Zu den weiteren Elementen gehören ein Dropdown-Kombinationsfeld zur Auswahl des Diagrammtyps, Steuerungsschaltflächen zum Drehen, Verschieben und Zoomen – je nach Diagrammtyp – sowie ein Tooltip für die Schaltflächen. Wie bei „ SmallGraphItem “ wird der angezeigte Diagrammtyp anhand des Zustands bestimmt.

Einstellungen

Die Einstellungen wurden aus dem Hauptinhalt Layout herausgelöst, da sie keine Teile der Dashboard- oder Details- Ansichten verwenden:

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

Die Ansicht „Einstellungen“ enthält ein weiteres „ BigGraphItem “ zur Darstellung des Diagramms sowie einen Einstellungsbereich zum Anpassen entweder der Eigenschaften von „ GraphsTheme “ oder einiger Eigenschaften, die spezifisch für den ausgewählten Diagrammtyp sind.

// 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
    ...
Globales Design

Die Einstellungen auf der Registerkarte „ General Settings “ wirken sich auf alle Diagramme in der Anwendung aus. Ein globales GraphsTheme wurde als „ Singleton “ unter „ GlobalSettings.qml “ implementiert:

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 ]
}

Dieses globale, gemeinsam genutzte Thema wird jedem Diagramm als Thema zugewiesen:

theme: GlobalSettings.theme

Da es sich um ein Singleton handelt, muss das „ GlobalSettings.qml “ auch im „ CMakeLists.txt “ als solches gekennzeichnet werden, damit es in der Anwendung verwendet werden kann:

set_source_files_properties(qml/GlobalSettings.qml
    PROPERTIES QT_QML_SINGLETON_TYPE TRUE)
Diagrammeinstellungen

Die Einstellungen auf der Registerkarte „ Graph Settings “ wirken sich nur auf das aktuell ausgewählte Diagramm aus. Diese Einstellungen ändern nicht das globale Design, sondern nur die Reihen im aktiven Diagramm.

Beispielprojekt @ 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.