QtQuick3D-例子-modelview3d

本文介绍了一款使用Qt Quick和Qt3D实现的动态立方体元素生成器,允许用户通过方向按钮在3D空间中创建和移动立方体,并通过颜色选择器更改立方体颜色。立方体可以通过点击进行删除操作。此应用展示了3D空间交互和实时渲染的基本概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

代码:

modelview3d.qml

import QtQuick 1.0
import Qt3D 1.0
import Qt3D.Shapes 1.0

Rectangle {
    id: topLevel
    width: 800; height: 480

   //数据模型
    ListModel {
        id: dynamicModel
        ListElement { x:0; y:0; z:0; color:"#ffffff"}
    }

    function addItem() {
        var newModelData = {
                                    "x": navigator.currentX/5,
                                    "y": navigator.currentY/5,
                                    "z": navigator.currentZ/5,
                                    "color": colorPicker.currentColor
        }
        dynamicModel.append( newModelData );
        viewport.update3d();
    }

    //立方体元素组件
    Component {
        id: cubeDelegate
        Cube {
            id: item
            x: model.x;y: model.y; z: model.z;
            effect: Effect {
                id: itemEffect
                color: model.color
                blending: true
            }
            scale:  1 / 5
            enabled: index != -1

            // You can have your own functions, signals, animations etc.
            onClicked: {
               onClicked: console.log("Cube("+index+") color: " + itemEffect.color);
                removeAnimation.start();
            }

            SequentialAnimation  {
                id: removeAnimation
                ColorAnimation { target: itemEffect; property: "color" ;from: model.color; to: Qt.rgba(0,0,0,0); duration: 500 }
                ScriptAction { script: {
                        dynamicModel.remove(index);
                        viewport.update3d();
                    }
                }
            }
            Component.onCompleted: {
                console.log("Cube Completed");
            }
        }
    } //--cubeDelegate end

    //三维视图
    Viewport {
        id: viewport
        picking: true
        blending: true

        Repeater {
            delegate: cubeDelegate
            model: dynamicModel
        }

        anchors.left: controlPanel.right
        anchors.right: parent.right
        anchors.top: parent.top
        anchors.bottom: parent.bottom

        camera: Camera {
            id: main_camera
            eye: Qt.vector3d(0, 4, 12)
        }
    }

   //颜色框 导航按钮以及说明
    Rectangle {
        id: controlPanel
        color: "#ffffff"
        width: 210
        anchors.top: parent.top
        anchors.bottom: parent.bottom
        anchors.left: parent.left

        Rectangle {
            id: colorPicker
            color: "white"
            height: sliderContainter.height + titleText.height + 5
            anchors.margins: 5
            anchors.left: parent.left
            anchors.right: parent.right
            anchors.top: parent.top

            Text {
                id: titleText
                text: qsTr("Color Picker")
                font.bold: true

                anchors.top: parent.top
                anchors.left:parent.left
                anchors.margins: 5
            }

            property color currentColor: "white"
            property real currentRed:       1.0
            property real currentGreen:    1.0
            property real currentBlue:      1.0
            property real currentAlpha:    1.0

            // We use Qt.rgba() to build the colour, which breaks the bindings,
            // so we update manually when the color components change.
            //和上面的属性绑定,当改变时自动调用
            onCurrentRedChanged: updateColor();
            onCurrentGreenChanged: updateColor();
            onCurrentBlueChanged: updateColor();
            onCurrentAlphaChanged: updateColor();

            function updateColor() {
                currentColor = Qt.rgba( colorPicker.currentRed,
                                                   colorPicker.currentGreen,
                                                   colorPicker.currentBlue,
                                                   colorPicker.currentAlpha);
                redSlider.updateColors();
                greenSlider.updateColors();
                blueSlider.updateColors();
                swatch.color = currentColor;
            }

            Rectangle {
                id: swatch
                anchors.margins: 5
                height: 90
                y: 5
                border.width: 2
                border.color: "black"
                color: Qt.rgba(colorPicker.currentRed,
                               colorPicker.currentGreen,
                               colorPicker.currentBlue,
                               colorPicker.currentAlpha);
                anchors.top: parent.top
                anchors.bottom: parent.bottom
                anchors.right: parent.right
                anchors.left: sliderContainter.right
            }

            Rectangle {
                id: sliderContainter
                anchors.bottom: parent.bottom
                width: 125
                height: 110

                Rectangle {
                    id: redSlider
                    property real currentValue: 1.0
                    rotation: -90
                    x: 30
                    y: -20
                    height: 80
                    width: 30
                    border.width: 2
                    border.color: "black"
                    radius: 5

                    property color zeroColor: Qt.rgba(0,
                                                      colorPicker.currentGreen,
                                                      colorPicker.currentBlue,
                                                      colorPicker.currentAlpha)
                    property color fullColor: Qt.rgba(1.0,
                                                      colorPicker.currentGreen,
                                                      colorPicker.currentBlue,
                                                      colorPicker.currentAlpha)

                    function updateColors()
                    {
                        zeroColor = Qt.rgba(0,
                                            colorPicker.currentGreen,
                                            colorPicker.currentBlue,
                                            colorPicker.currentAlpha);
                        fullColor = Qt.rgba(1.0,
                                            colorPicker.currentGreen,
                                            colorPicker.currentBlue,
                                            colorPicker.currentAlpha);
                    }

                    //定义一个颜色梯度
                    gradient: Gradient {
                        GradientStop {
                            position: 0.0
                            color: redSlider.zeroColor}
                        GradientStop {
                            position: 1.0
                            color: redSlider.fullColor
                        }
                    }
                    MouseArea {
                        anchors.fill: parent
                        onMousePositionChanged: {
                            redSlider.currentValue = mouseY / redSlider.height;
                            colorPicker.currentRed = redSlider.currentValue;
                        }
                    }
                }

                Rectangle {
                    id: redSwatch
                    width: redSlider.width
                    height: redSlider.width
                    color: Qt.rgba(1.0, 0, 0);
                    border.width: 2
                    border.color: "black"

                    x: redSlider.height + 10
                    y: 5
                    radius: 5
                    MouseArea {
                        anchors.fill: parent
                        onClicked: {colorPicker.currentRed = 1.0;
                            colorPicker.currentGreen = 0;
                            colorPicker.currentBlue = 0}
                    }
                }

                Rectangle {
                    id: greenSlider
                    rotation: -90
                    x: 30
                    y: 15
                    height: 80
                    width: 30

                    property color zeroColor: Qt.rgba(colorPicker.currentRed,
                                                      0.0,
                                                      colorPicker.currentBlue,
                                                      colorPicker.currentAlpha)
                    property color fullColor: Qt.rgba(colorPicker.currentRed,
                                                      1.0,
                                                      colorPicker.currentBlue,
                                                      colorPicker.currentAlpha)

                    function updateColors()
                    {
                        zeroColor = Qt.rgba(colorPicker.currentRed,
                                            0.0,
                                            colorPicker.currentBlue,
                                            colorPicker.currentAlpha);
                        fullColor = Qt.rgba(colorPicker.currentRed,
                                            1.0,
                                            colorPicker.currentBlue,
                                            colorPicker.currentAlpha);
                    }

                    gradient: Gradient {
                        GradientStop {
                            position: 0.0
                            color: greenSlider.zeroColor
                        }
                        GradientStop {
                            position: 1.0
                            color: greenSlider.fullColor
                        }
                    }
                    border.width: 2
                    border.color: "black"
                    radius: 5
                    MouseArea {
                        anchors.fill: parent
                        onMousePositionChanged: {
                            colorPicker.currentGreen = mouseY / greenSlider.height;
                        }
                    }
                }

                Rectangle {
                    id: greenSwatch
                    width: greenSlider.width
                    height: greenSlider.width
                    color: Qt.rgba(0, 1, 0);
                    border.width: 2
                    border.color: "black"

                    x: greenSlider.height + 10
                    y: 40
                    radius: 5
                    MouseArea {
                        anchors.fill: parent
                        onClicked: {
                            colorPicker.currentRed = 0;
                            colorPicker.currentGreen = 1;
                            colorPicker.currentBlue = 0
                        }
                    }
                }

                Rectangle {
                    id: blueSlider
                    rotation: -90
                    x: 30
                    y: 50
                    height: 80
                    width: 30
                    property color zeroColor: Qt.rgba(colorPicker.currentRed,
                                                      colorPicker.currentGreen,
                                                      0.0,
                                                      colorPicker.currentAlpha)
                    property color fullColor: Qt.rgba(colorPicker.currentRed,
                                                      colorPicker.currentGreen,
                                                      1.0,
                                                      colorPicker.currentAlpha)

                    function updateColors()
                    {
                        zeroColor = Qt.rgba(colorPicker.currentRed,
                                            colorPicker.currentGreen,
                                            0.0,
                                            colorPicker.currentAlpha);
                        fullColor = Qt.rgba(colorPicker.currentRed,
                                            colorPicker.currentGreen,
                                            1.0,
                                            colorPicker.currentAlpha);
                    }

                    gradient: Gradient {
                        GradientStop {
                            position: 0.0
                            color: blueSlider.zeroColor
                        }
                        GradientStop {
                            position: 1.0
                            color: blueSlider.fullColor
                        }
                    }
                    border.width: 2
                    border.color: "black"
                    radius: 5
                    MouseArea {
                        anchors.fill: parent
                        onClicked: {
                            colorPicker.currentBlue =
                                    mouseY / blueSlider.height;
                        }
                        onMousePositionChanged: {
                            colorPicker.currentBlue =
                                    mouseY / blueSlider.height;
                        }
                    }
                }

                Rectangle {
                    id: blueSwatch
                    width: blueSlider.width
                    height: blueSlider.width
                    color: Qt.rgba(0, 0, 1);
                    border.width: 2
                    border.color: "black"

                    x: blueSlider.height + 10
                    y: 75
                    radius: 5
                    MouseArea {
                        anchors.fill: parent
                        onClicked: {
                            colorPicker.currentRed = 0;
                            colorPicker.currentGreen = 0;
                            colorPicker.currentBlue = 1
                        }
                    }
                }
            }
        }

        //导航
        Rectangle {
            id: navigator
            height: 200
            anchors.margins: 5
            anchors.top: colorPicker.bottom
            anchors.left: parent.left
            anchors.right: parent.right

            // These properties contain are used by the modelview to populate
            // new elements
            property int currentX:0;
            property int currentY:0;
            property int currentZ:0;

            property int buttonWidth: 45
            property int buttonHeight: 30

            Button {
                width: navigator.buttonWidth
                height: navigator.buttonHeight
                anchors.horizontalCenter: parent.horizontalCenter
                anchors.top: parent.top
                text: qsTr("Up")
                onClicked: {
                    navigator.currentY += 1;
                    topLevel.addItem();
                }
            }

            Button {
                width: navigator.buttonWidth
                height: navigator.buttonHeight
                anchors.horizontalCenter: parent.horizontalCenter
                anchors.bottom: parent.bottom
                text: qsTr("Down")
                onClicked: {
                    navigator.currentY -= 1;
                    topLevel.addItem();
                }
            }

            Button {
                width: navigator.buttonWidth
                height: navigator.buttonHeight
                anchors.left: parent.left
                anchors.verticalCenter: parent.verticalCenter
                text: qsTr("Left")
                onClicked: {
                    navigator.currentX -= 1;
                    topLevel.addItem();
                }
            }

            Button {
                width: navigator.buttonWidth
                height: navigator.buttonHeight
                anchors.right: parent.right
                anchors.verticalCenter: parent.verticalCenter
                text: qsTr("Right")
                onClicked: {
                    navigator.currentX += 1;
                    topLevel.addItem();
                }
            }

            Button {
                width: navigator.buttonWidth
                height: navigator.buttonHeight
                anchors.right: parent.right
                anchors.top: parent.top
                text: qsTr("In")
                onClicked: {
                    navigator.currentZ -= 1;
                    topLevel.addItem();
                }
            }

            Button {
                width: navigator.buttonWidth
                height: navigator.buttonHeight
                anchors.left: parent.left
                anchors.bottom: parent.bottom
                text: qsTr("Out")
                onClicked: {
                    navigator.currentZ += 1;
                    topLevel.addItem();
                }
            }

            Image {
                id: axesImage
                anchors.centerIn: parent
                source: "axes.png"

                property color buttonColor: "#448888"
            }
        }

        //说明文字
        Rectangle {
            id: instructions
            anchors.margins: 5
            anchors.top: navigator.bottom
            anchors.left: parent.left
            anchors.bottom: parent.bottom
            anchors.right: navigator.right
            Text {
                anchors.fill: parent
                id: instructionsText
                wrapMode: Text.WordWrap
                text: qsTr("Use this navigator to create new boxes and move around"
                           + " 3d space.\n"
                           + "Use the color picker to change the color of "
                           + "generated cubes."
                           //                       + "\n  Click on cubes to remove them from the scene."
                           )
            }
        }
    }
}

 

Button.qml

import QtQuick 1.0

Rectangle {
    id: button
    color: mouseArea.pressed ? "#000000" : "#ffffff"
    border.width: 1
    anchors.margins: 5
    radius: 5

    property alias text : text.text //页面显示的文字
    signal clicked; //单击信号

    Text {
        id: text
        color: mouseArea.pressed ? "#ffffff" : "#000000";
        anchors.centerIn: parent
        text: qsTr("A Button")
    }
    MouseArea {
        id: mouseArea
        anchors.fill: parent
        onClicked: button.clicked()

    }
}

 

操作:

点击当方向按钮时动态向模式中添加立方体元素,

点击模式中立方体元素时,删除

问题:

1.属性绑定

 propertyreal currentRed:       1.0

和currentRed属性自动绑定,当值改变自动调用下面的函数

onCurrentRedChanged:updateColor();

2. 通过Repeater动态向Viewport中添加三维元素


Button.qmlButton.qmlButton.qml

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值