简单散点图

在 QML 应用中使用 Scatter3D

简单散点图 展示了如何使用 Scatter3D 和 QML 创建简单的散点图可视化。

关于如何与图表交互的说明,请参阅 此页

有关如何创建自己的新 Qt Quick 应用的说明,请参阅 Qt Creator 帮助。

运行示例

要从 Qt Creator 运行示例,请打开 欢迎 模式并从 示例 中选择示例。有关更多信息,请访问 构建和运行示例

布局设置

在深入了解 QML 代码之前,main.cpp 设置了应用程序。从资源(qrc:)读取 main.qml 文件。

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

main.qml 文件是应用程序 QML 代码的起点。首先,导入所有所需的 QML 模块。

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

然后,创建一个 Data 项目,该项目将作为包含图表数据的项。

Data {
    id: seriesData
}

接下来,创建两个 Theme3D 项目,定义两个不同的主题,一个是 Qt 主题,另一个是复古主题。

Theme3D {
    id: themeQt
    type: Theme3D.Theme.Qt
    font.pointSize: 40
}

Theme3D {
    id: themeRetro
    type: Theme3D.Theme.Retro
}

此应用程序的布局将包括五个不同的按钮来切换图表的不同的视觉选项是开还是关,当然还有图表本身。有多种组织方式,其中一种是在一个 GridLayout 中包含四个按钮、Graph 和第五个按钮,所有这些都在一个 ColumnLayout 中。

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

GridLayout 是响应式的。这意味着使用的列数取决于应用程序窗口的宽度。这是通过将 columns 属性分配给三元运算符来实现的,这取决于窗口宽度,解算为 1、2 或 4。

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)

在此 GridLayout 中,实例化了四个 RoundButton。一个用于切换阴影,一个用于网格平滑,一个用于摄像机位置,最后,一个用于更改图表的背景。所有按钮都遵循相同的结构。而不是为所有按钮重新定义此结构,可以创建一个自定义组件。

component CustomButton : RoundButton {
    id: buttonRoot

CustomButtom 扩展了 RoundButton 类型,但添加了一些扩展。设置了诸如 Layout.minimumWidthLayout.FillWidthradiusbackground 等属性。这些定义了按钮的样式和布局。

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: Row {
    id :content
    IconImage {
        id: iconImage
        width: iconDimension
        height: iconDimension
        color: "transparent"
    }
    Label {
        text: buttonRoot.text
        horizontalAlignment: Text.AlignLeft
        anchors.verticalCenter: parent.verticalCenter
    }
}

中创建四个。需要设置三个属性,即图标图像和文本的两个别名,以及信号

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

例如,阴影按钮将信号设置为切换阴影的开和关。

设置Graph

布局中的下一个是,它在自己的 QML文件中定义,如下所述实例化

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

查看其在中的实现,该图是类型,嵌套在类型内部。

Scatter3D {
    id: scatterGraph

在定义数据集之前,需要配置一些轴属性。

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"

设置Data

图形显示了三个数据集,表示中给出的数据。数据集存储在类型中

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

并使用暴露给其他文件

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

在这些别名被使用之前,创建一个类型,其中包含一个项目。

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

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

此数据代理使用属性引用中的数据集。上述提到的别名是通过在中实例化的类型的,即来访问的。

itemModel: seriesData.model

对剩余两个数据集重复此操作。

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

好了,现在散点图现在指向三个数据集。

剩下要做的就是将剩余的按钮,即,添加到我们的。与此按钮的唯一区别是它布局在左手的 side。这是通过将属性设置为以及设置为来设置的。

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

示例内容

@ code.qt.io的示例项目

© 2024 The Qt Company Ltd。本文件中包含的文档贡献是其各自所有者的版权。本文件提供的文档是在自由软件基金会根据的条款下发布的