简单散点图

在 QML 应用中使用 Scatter3D

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

有关如何与图形交互的说明,请参阅 此页面

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

运行示例

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

应用基础

在深入 QML 代码之前,先看看应用 main.cpp

此应用在 UI 中实现了一个 '退出' 按钮,因此您需要将 QQmlEngine::quit() 信号连接到应用 QWindow::close() 插槽

QObject::connect(viewer.engine(), &QQmlEngine::quit, &viewer, &QWindow::close);

为了使部署更加简单,将所有应用程序的 .qml 文件收集到一个资源文件(qmlscatter.qrc)中

<RCC>
    <qresource prefix="/">
        <file>qml/qmlscatter/Data.qml</file>
        <file>qml/qmlscatter/main.qml</file>
    </qresource>
</RCC>

这也要求将 main.qml 设置为从资源(qrc:)读取

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

当使用 cmake 而不是 qmake 时,将 .qml 文件添加到 CMakeLists.txt 中的 QML 模块中

qt6_add_qml_module(qmlscatter
    URI Scatter
    VERSION 1.0
    NO_RESOURCE_TARGET_PATH
    QML_FILES
        qml/qmlscatter/Data.qml
        qml/qmlscatter/main.qml
)

最后,将应用设置为在最大化窗口中运行

viewer.showMaximized();

设置图形

首先,导入所有需要的 QML 模块

import QtQuick
import QtQuick.Controls
import QtDataVisualization

然后,创建主要的 Item 并将其命名为 mainView

Item {
    id: mainView

然后,在主 Item 中添加另一个 Item,并称其为 dataView。这将是包含 Scatter3D 图形的项。将其锚定到父项的底部

Item {
    id: dataView
    anchors.bottom: parent.bottom

接下来,添加 Scatter3D 图形本身。将其添加到 dataView 中,并命名为 scatterGraph。使其填充 dataView

Scatter3D {
    id: scatterGraph
    anchors.fill: parent

现在图形已经准备好了,但没有任何数据。它也有默认的轴和视觉属性。

接下来,首先修改一些视觉属性,如下所示在 scatterGraph 中添加

theme: themeQt
shadowQuality: AbstractGraph3D.ShadowQualityHigh
scene.activeCamera.cameraPreset: Camera3D.CameraPresetFront

添加了自定义主题,更改了阴影质量,并调整了摄像机位置。其他视觉属性很好,所以不需要更改它们。

自定义主题基于预定义的主题,Theme3D.ThemeQt,但改变了其中的字体

Theme3D {
    id: themeQt
    type: Theme3D.ThemeQt
    font.pointSize: 40
}

然后,开始向图形中添加一些数据。

向图中添加数据

mainView内部创建一个Data项目,并将其命名为seriesData

Data {
    id: seriesData
}

seriesData项目包含本示例中所有三个序列所使用的数据模型。

这是在Data.qml中保存数据的组件。它以Item为主要组件。

在主组件中,将数据本身添加到ListModel中,并将其命名为dataModel

ListModel {
    id: dataModel
    ListElement{ xPos: -10.0; yPos: 5.0; zPos: -5.0 }
    ...

将其他两个系列也添加两个此类组件,并将其命名为dataModelTwodataModelThree.

然后,将数据模型公开,以便可以从main.qml中使用。通过在主数据组件中将它们定义为别名来执行此操作

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

现在,您可以使用Data.qml中的数据与main.qml中的scatterGraph一起使用。首先,添加一个< wurden enthältgeScatter3DSeries并将其称为scatterSeries

Scatter3DSeries {
    id: scatterSeries

然后,设置序列的选择标签格式

itemLabelFormat: "Series 1: X:@xLabel Y:@yLabel Z:@zLabel"

最后,将系列一的数据添加到ItemModelScatterDataProxy中。将数据本身作为代理的itemModel

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

以相同的方式添加其他两个系列,但修改一些具有特定系列功能的细节

Scatter3DSeries {
    id: scatterSeriesTwo
    itemLabelFormat: "Series 2: X:@xLabel Y:@yLabel Z:@zLabel"
    itemSize: 0.05
    mesh: Abstract3DSeries.MeshCube
    ...

然后,稍微修改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"

之后,在mainView中添加一些按钮来控制图形,其中一个作为示例进行了展示

Button {
    id: shadowToggle
    width: mainView.buttonWidth // Calculated elsewhere based on screen orientation
    anchors.left: parent.left
    anchors.top: parent.top
    anchors.margins: 5
    text: scatterGraph.shadowsSupported ? "Hide Shadows" : "Shadows not supported"
    enabled: scatterGraph.shadowsSupported
    onClicked: {
        if (scatterGraph.shadowQuality === AbstractGraph3D.ShadowQualityNone) {
            scatterGraph.shadowQuality = AbstractGraph3D.ShadowQualityHigh;
            text = "Hide Shadows";
        } else {
            scatterGraph.shadowQuality = AbstractGraph3D.ShadowQualityNone;
            text = "Show Shadows";
        }
    }
}

然后,修改dataView以在顶部为按钮留出空间

Item {
    id: dataView
    anchors.bottom: parent.bottom
    width: parent.width
    // Adjust the space based on screen orientation:
    // If we're in portrait mode, we have 3 rows of buttons, otherwise they are all in one row.
    height: parent.height - (mainView.portraitMode ? shadowToggle.implicitHeight * 3 + 25
                                                   : shadowToggle.implicitHeight + 10)
    ...

现在已完成!

示例内容

示例项目 @ code.qt.io

© 2024 Qt 公司 Ltd。此处包含的文档贡献是各自拥有者的版权。本提供的文档是根据由自由软件基金会发布的< a href="http://www.gnu.org/licenses/fdl.html">GNU自由文档许可证版本 1.3 许可的。Qt及其相关标志是芬兰的Qt公司及其在全球的注册商标。所有其他商标均为其各自拥有者的财产。