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 RoundButton
instanziiert. 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 CustomButton
erstellt. 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 alias
es 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
© 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.