Einfaches Punktediagramm

Verwendung von Scatter3D in einer QML-Anwendung.

Simple Scatter Graph zeigt, wie man ein einfaches Streudiagramm mit Scatter3D und QML visualisiert.

Eine Anleitung zur Interaktion mit dem Diagramm finden Sie auf dieser Seite.

Anweisungen zum Erstellen einer neuen Qt Quick Anwendung finden Sie in der Hilfe von Qt Creator.

Ausführen des Beispiels

Zum Ausführen des Beispiels von Qt Creatorzu starten, öffnen Sie den Modus Welcome und wählen Sie das Beispiel aus Examples. Weitere Informationen finden Sie unter Erstellen und Ausführen eines Beispiels.

Einrichten des Layouts

Bevor Sie sich mit dem QML-Code befassen, richtet main.cpp die Anwendung ein. Die Datei main.qml wird aus der Ressource (qrc:) gelesen.

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

Diese main.qml Datei ist der Ausgangspunkt für den QML-Code der Anwendung. Importieren Sie zunächst alle erforderlichen QML-Module:

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

Erstellen Sie dann ein Element Data, das die Daten für das Diagramm enthält.

Data {
    id: seriesData
}

Als nächstes erstellen Sie zwei GraphsTheme Elemente, die zwei verschiedene Themen für den Graphen definieren, ein Qt Green Thema und ein Qt Neon Green Thema.

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

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

Das Layout für diese Anwendung wird aus fünf verschiedenen Schaltflächen bestehen, mit denen verschiedene visuelle Optionen für das Diagramm ein- und ausgeschaltet werden können, und natürlich dem Diagramm selbst. Es gibt viele Möglichkeiten, diese zu organisieren. Eine Möglichkeit ist, eine GridLayout mit vier Schaltflächen, die Graph und die fünfte Schaltfläche, die alle in einer ColumnLayout erscheinen.

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

Die GridLayout ist reaktionsfähig. Das bedeutet, dass die Anzahl der verwendeten Spalten von der Breite des Anwendungsfensters abhängt. Dazu wird der Eigenschaft columns ein ternärer Operator zugewiesen, der je nach Fensterbreite entweder 1, 2 oder 4 ergibt.

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)

In dieser GridLayout werden vier RoundButtoninstanziiert. Eine für das Umschalten der Schatten, eine für das Glätten des Netzes, eine für die Kameraposition und schließlich eine für das Ändern des Hintergrunds der Grafik. Alle Schaltflächen folgen der gleichen Struktur. Anstatt diese Struktur für alle Schaltflächen neu zu definieren, kann eine eigene Komponente erstellt werden.

component CustomButton : RoundButton {
    id: buttonRoot

CustomButtom erweitert den Typ RoundButton, fügt aber ein paar Ergänzungen hinzu. Es werden Eigenschaften wie Layout.minimumWidth, Layout.FillWidth, radius und background festgelegt. Diese definieren das Styling und Layout der Schaltfläche.

property alias source: iconImage.source

Layout.minimumWidth: buttonMinWidth
Layout.fillWidth: true

radius: mainView.radius

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

contentItem hingegen definiert den Inhalt der Schaltfläche, in diesem Fall einen Row Typ, der ein Symbol und etwas Text enthält. Das Symbol wird mit Hilfe eines Image -Typs importiert und die Eigenschaft source gesetzt. Der Text wird mit einem Typ Label erstellt und mit der Eigenschaft text festgelegt. Für diese beiden Eigenschaften werden oben in der benutzerdefinierten Komponente zwei Verknüpfungen erstellt, damit sie bei der Erstellung einer Instanz von CustomButton festgelegt werden können.

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

In der GridLayout werden vier CustomButtonerstellt. Drei Eigenschaften müssen festgelegt werden, die beiden Zuordnungen für das Symbolbild und den Text sowie das 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
    }
}

Die Schaltfläche "Schatten" zum Beispiel setzt das Zeichen onClicked, um den Schatten ein- und auszuschalten.

Einrichten des Diagramms

Der nächste Schritt im Layout ist die Graph, die in einer eigenen QML-Datei Graph.qml definiert ist und wie folgt instanziiert wird:

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

Wenn man sich die Implementierung in Graph.qml ansieht, ist der Graph vom Typ Scatter3D, der in einem Typ Item verschachtelt ist.

Scatter3D {
    id: scatterGraph

Bevor die Datensätze definiert werden, werden einige der Achseneigenschaften konfiguriert.

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"

Einrichten der Daten

Das Diagramm zeigt drei Datensätze, die die in Data.qml angegebenen Daten darstellen. Die Datensätze sind in ListModel Typen gespeichert

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

gespeichert und den anderen Dateien über property aliases zugewiesen.

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

Bevor diese Aliasnamen verwendet werden, erstellen Sie einen Typ Scatter3DSeries, der ein Element ItemModelScatterDataProxy enthält.

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

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

Dieser Daten-Proxy verweist über seine Eigenschaft itemModel auf die Datensätze in Data.qml. Der Zugriff auf die oben genannten Aliase erfolgt über die id des Data Typs, der in main.qml, seriesData instanziiert ist.

itemModel: seriesData.model

Wiederholen Sie diesen Vorgang für die beiden anderen Datensätze.

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

Gut, das Punktdiagramm zeigt jetzt auf die drei Datensätze.

Jetzt müssen wir nur noch die verbleibende Schaltfläche theme button zu ColumnLayout hinzufügen. Der einzige Unterschied bei dieser Schaltfläche ist, dass sie auf der linken Seite des Layouts positioniert ist. Dies wird festgelegt, indem die Eigenschaft Layout.alignment auf Qt.AlignLeft und Layout.fillWidth auf false gesetzt wird.

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

Beispiel Inhalt

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