QtQuick 2 - 侧面板示例

QtQuick 2 - Side Panel example

有人可以帮助我理解这段代码的行为吗?我写了侧面板菜单的简单示例(现在只是模板)并且使用 onMenuVisibleChanged 插槽存在问题(但我需要的只是实际工作,只是想了解为什么另一种方式不行)。从逻辑上讲,它应该将面板矩形的 x 更改为指定值,但它没有。请帮助我理解这件事的正确方法。

main.qml

import QtQuick 2.3
import QtQuick.Controls 1.3
import QtQuick.Window 2.2
import QtQuick.Dialogs 1.2

ApplicationWindow {
    title: qsTr("Hello World")
    width: 640
    height: 480
    visible: true
    menuBar: MenuBar{
        Menu{
            title: "File"
        MenuItem{
            text: "Exit"
            onTriggered: Qt.quit()
        }
        }
    }
    SidePane{
        id: sidePane
        menuWidth: 350
        z: 2
    }
}

SidePane.qml

import QtQuick 2.3
import QtQuick.Window 2.2

Item {
    id: screenItem
    anchors.fill: parent
    function show() {
        rect.x = 0
        menuVisible = true
    }
    function hide() {
        rect.x = -rect.width
        menuVisible = false
    }
    property int animationDuration: 200
    property bool menuVisible: false
    property int dragThreshold: 120
    property int menuWidth: 300
    Rectangle {
        id: rect
        width: menuWidth
        x: -rect.width
        height: Screen.height
        color: "lightsteelblue"
        Drag.active: menuDragArea.drag.active
        Behavior on x {
            NumberAnimation {
                duration: animationDuration
                easing.type: Easing.InOutQuad
            }
        }
        MouseArea {
            property int dragX: 0
            property int startX: 0
            property int diffX: 0
            id: menuDragArea
            hoverEnabled: true
            height: rect.height
            width: rect.width + 40
            anchors.left: rect.left
            drag.target: rect
            drag.axis: Drag.XAxis
            drag.minimumX: -rect.width
            drag.maximumX: 0
            onPressed: startX = rect.x + rect.width
            onReleased: {
                dragX = rect.x + rect.width
                diffX = Math.abs(startX - dragX)
                if ((diffX > dragThreshold) && (startX == 0)){
                    rect.x = 0
                    menuVisible = true
                } else if ((diffX < dragThreshold) && (startX == 0)){
                    rect.x = -rect.width
                    menuVisible = false
                }
                if ((diffX > dragThreshold) && (startX == rect.width)){
                    rect.x = -rect.width
                    menuVisible = false
                } else if ((diffX < dragThreshold) && (startX == rect.width)){
                    rect.x = 0
                    menuVisible = true
                }
            }
        }
    }
    Rectangle{
        id: shadowRect
        anchors.left: rect.right
        anchors.right: screenItem.right
        opacity: (rect.x + rect.width) / (rect.width * 2.2)
        color: "black"
        height: screenItem.height
        MouseArea{
            id: shadowArea
            anchors.fill: shadowRect
            visible: menuVisible ? true : false
            hoverEnabled: true
            onClicked: {
                if (menuVisible == true){
                    rect.x = -rect.width
                    menuVisible = false
                }
            }
        }
        Rectangle{
            id: shadowRect2
            color: "black"
            anchors.left: parent.left
            width: 5
            opacity: (rect.x + rect.width) / (rect.width * 2)
            height: screenItem.height
        }
        Rectangle{
            id: shadowRect3
            color: "black"
            anchors.left: parent.left
            width: 3
            opacity: (rect.x + rect.width) / (rect.width * 1.9)
            height: screenItem.height
        }
    }
    onMenuVisibleChanged: menuVisible ? rect.x = 0 : rect.x = -rect.width
}

感谢任何帮助。只是一个 QML 初学者。最主要的目的是在 android 应用程序中使用此面板。如果需要,请随意使用此代码。

属性 drag 使 x 值可拖动

如果您通过 mouseX onPressed/onReleased 实现它,rect.x 将是 0-rect.width onMenuVisibleChanged

MouseArea {
        property int dragX: 0
        property int startX: 0
        property int diffX: 0
        id: menuDragArea
        hoverEnabled: true
        height: rect.height
        width: rect.width + 40
        anchors.left: rect.left

        onPressed: {
            startX = mouseX;
            console.log(rect.x)
        }
        onReleased: {
            diffX = Math.abs(startX - mouseX)
            console.log("diff:"+diffX)
            if ((diffX > dragThreshold) && (mouseX > startX) && (rect.x !=0 )){
                rect.x = 0
                menuVisible = true
            } else if ((diffX > dragThreshold) && (mouseX < startX) && (rect.x == 0)){
                rect.x = -rect.width
                menuVisible = false
            }
        }
    }

视觉拖拽,不好意思丑了:

MouseArea {
        property int startX: 0
        property int diffX: 0
        property int startRectX: 0
        property bool isPressed: false
        id: menuDragArea
        hoverEnabled: true
        height: rect.height
        width: rect.width + 40
        anchors.left: rect.left
        onPressed: {
            startX = mouseX;
            startRectX = rect.x
            isPressed = true
            console.log(rect.x)}
        onMouseXChanged: {
            if(isPressed)
                rect.x = (mouseX>rect.width)? 0 : (mouseX-rect.width)
        }
        onReleased: {
            isPressed = false
            diffX = Math.abs(startX - mouseX)
            console.log("diff:"+diffX)
            if ((mouseX >= startX) && (startRectX == -rect.width )){
                if(diffX > dragThreshold)
                {
                    rect.x = 0
                    menuVisible = true
                }
                else
                    rect.x = startRectX
            } else if ((mouseX <= startX) && (startRectX == 0)){
                if(diffX > dragThreshold)
                {
                    rect.x = -rect.width
                    menuVisible = false
                }
                else
                    rect.x = startRectX
            }
            else
                rect.x = startRectX
        }
    }