Qt Quick 2 Surface Multiseries Example

Using multiple series with Surface3D in a QML application.

The Qt Quick 2 surface example shows how to make a 3D surface plot displaying 3 layers using Surface3D with Qt Quick 2.

The focus in this example is on generating a multiseries surface plot from 3 different height map images, so in this section we skip explaining the application creation. For a more detailed QML example documentation, see Qt Quick 2 Scatter Example .

运行范例

要运行范例从 Qt Creator ,打开 欢迎 模式,然后选择范例从 范例 。更多信息,拜访 构建和运行范例 .

把数据添加到图形

This example shows how to add several surface series to one graph using using HeightMapSurfaceDataProxies and how to control their visibilities individually.

Let's start by creating a specific gradient for each layer:

ColorGradient {
    id: layerOneGradient
    ColorGradientStop { position: 0.0; color: "black" }
    ColorGradientStop { position: 0.31; color: "tan" }
    ColorGradientStop { position: 0.32; color: "green" }
    ColorGradientStop { position: 0.40; color: "darkslategray" }
    ColorGradientStop { position: 1.0; color: "white" }
}
ColorGradient {
    id: layerTwoGradient
    ColorGradientStop { position: 0.315; color: "blue" }
    ColorGradientStop { position: 0.33; color: "white" }
}
ColorGradient {
    id: layerThreeGradient
    ColorGradientStop { position: 0.0; color: "red" }
    ColorGradientStop { position: 0.15; color: "black" }
}
					

Then we'll create the series themselves. It happens simply by adding 3 separate Surface3DSeries Surface3D graph as children:

...
Surface3DSeries {
    id: layerOneSeries
    baseGradient: layerOneGradient
    HeightMapSurfaceDataProxy {
        heightMapFile: ":/heightmaps/layer_1.png"
    }
    flatShadingEnabled: false
    drawMode: Surface3DSeries.DrawSurface
    visible: layerOneToggle.checked // bind to checkbox state
}
Surface3DSeries {
    id: layerTwoSeries
    baseGradient: layerTwoGradient
    HeightMapSurfaceDataProxy {
        heightMapFile: ":/heightmaps/layer_2.png"
    }
    flatShadingEnabled: false
    drawMode: Surface3DSeries.DrawSurface
    visible: layerTwoToggle.checked // bind to checkbox state
}
Surface3DSeries {
    id: layerThreeSeries
    baseGradient: layerThreeGradient
    HeightMapSurfaceDataProxy {
        heightMapFile: ":/heightmaps/layer_3.png"
    }
    flatShadingEnabled: false
    drawMode: Surface3DSeries.DrawSurface
    visible: layerThreeToggle.checked // bind to checkbox state
}
...
					

You'll notice we added the created gradients to the baseGradient properties of the series. We could have added them to the baseGradients 特性为 Theme3D in Surface3D instead, but doing it this way ensures each gradient is applied to a correct series:

Surface3DSeries {
    id: layerOneSeries
    baseGradient: layerOneGradient
    ...
					
					

Controlling the Graph

Let's add some checkboxes to control the visibility of layers:

GroupBox {
    flat: true
    Layout.fillWidth: true
    Column {
        spacing: 10
        Label {
            font.pointSize: fontSize
            font.bold: true
            text: "Layer Selection"
        }
        CheckBox {
            id: layerOneToggle
            checked: true
            style: CheckBoxStyle {
                label: Label {
                    font.pointSize: fontSize
                    text: "Show Ground Layer"
                }
            }
        }
        CheckBox {
            id: layerTwoToggle
            checked: true
            style: CheckBoxStyle {
                label: Label {
                    font.pointSize: fontSize
                    text: "Show Sea Layer"
                }
            }
        }
        CheckBox {
            id: layerThreeToggle
            checked: true
            style: CheckBoxStyle {
                label: Label {
                    font.pointSize: fontSize
                    text: "Show Tectonic Layer"
                }
            }
        }
    }
}
					

We don't need to do anything on the onCheckedChanged as we bound the checked state to the visible property of the series directly:

...
visible: layerOneToggle.checked // bind to checkbox state
...
					

Let's add some more checkboxes to control how the layers are displayed, when visible:

GroupBox {
    flat: true
    Layout.fillWidth: true
    Column {
        spacing: 10
        Label {
            font.pointSize: fontSize
            font.bold: true
            text: "Layer Style"
        }
        CheckBox {
            id: layerOneGrid
            style: CheckBoxStyle {
                label: Label {
                    font.pointSize: fontSize
                    text: "Show Ground as Grid"
                }
            }
            onCheckedChanged: {
                if (checked)
                    layerOneSeries.drawMode = Surface3DSeries.DrawWireframe
                else
                    layerOneSeries.drawMode = Surface3DSeries.DrawSurface
            }
        }
        CheckBox {
            id: layerTwoGrid
            style: CheckBoxStyle {
                label: Label {
                    font.pointSize: fontSize
                    text: "Show Sea as Grid"
                }
            }
            onCheckedChanged: {
                if (checked)
                    layerTwoSeries.drawMode = Surface3DSeries.DrawWireframe
                else
                    layerTwoSeries.drawMode = Surface3DSeries.DrawSurface
            }
        }
        CheckBox {
            id: layerThreeGrid
            style: CheckBoxStyle {
                label: Label {
                    font.pointSize: fontSize
                    text: "Show Tectonic as Grid"
                }
            }
            onCheckedChanged: {
                if (checked)
                    layerThreeSeries.drawMode = Surface3DSeries.DrawWireframe
                else
                    layerThreeSeries.drawMode = Surface3DSeries.DrawSurface
            }
        }
    }
}
					

In addition to these we have three buttons, one of which is of special interest to us. It is used to control whether we want to slice into only one layer, or all of them:

NewButton {
    id: sliceButton
    text: "Slice All Layers"
    fontSize: fontSize
    Layout.fillWidth: true
    Layout.minimumHeight: 40
    onClicked: {
        if (surfaceLayers.selectionMode & AbstractGraph3D.SelectionMultiSeries) {
            surfaceLayers.selectionMode = AbstractGraph3D.SelectionRow
                    | AbstractGraph3D.SelectionSlice
            text = "Slice All Layers"
        } else {
            surfaceLayers.selectionMode = AbstractGraph3D.SelectionRow
                    | AbstractGraph3D.SelectionSlice
                    | AbstractGraph3D.SelectionMultiSeries
            text = "Slice One Layer"
        }
    }
}
					
					

范例内容

范例工程 @ code.qt.io