zoukankan      html  css  js  c++  java
  • QML间接连接(Connecting Indirectly)和间接绑定(Binding Indirectly)

    间接连接(Connecting Indirectly)

    间接连接允许我们在运行时更改Connections的target.
    使用QML时, 有时需要在运行时, 监控不同的对象的信号. 可采用以下方法动态更改Connections的target属性实现.

    代码如下

    Rectangle {
        id: container
         600
        height: 400
        color: "white"
        //左侧两个矩形布局
        Column {
            anchors.top: parent.top
            anchors.left: parent.left
            spacing: 20
            Rectangle {
                 290
                height: 50
                color: "lightGray"
                MouseArea {
                    anchors.fill: parent
                    onClicked: container.state = "left"
                }
                Text {
                    anchors.centerIn: parent
                    font.pixelSize: 30
                    text: container.state==="left"?"Active":"inactive";
                }
            }
            // M1>>
            Rectangle {
                id: leftRectangle
                 290
                height: 200
                color: "green"
                MouseArea {
                    id: leftMouseArea
                    anchors.fill: parent
                    onClicked: leftClickedAnimation.start();
                }
                Text {
                    anchors.centerIn: parent
                    font.pixelSize: 30
                    color: "white"
                    text: "Click me!"
                }
            }
            // <<M1
        }
        //右侧两个矩形布局
        Column {
            anchors.top: parent.top
            anchors.right: parent.right
            spacing: 20
            Rectangle {
                 290
                height: 50
                color: "lightGray"
                MouseArea {
                    anchors.fill: parent
                    onClicked: container.state = "right"
                }
                Text {
                    anchors.centerIn: parent
                    font.pixelSize: 30
                    text: container.state==="right"?"Active":"inactive";
                }
            }
            Rectangle {
                id: rightRectangle
                 290
                height: 200
                color: "blue"
                MouseArea {
                    id: rightMouseArea
                    anchors.fill: parent
                    onClicked: rightClickedAnimation.start();
                }
                Text {
                    anchors.centerIn: parent
                    font.pixelSize: 30
                    color: "white"
                    text: "Click me!"
                }
            }
        }
        //下方字体
        Text {
            id: activeText
            anchors.horizontalCenter: parent.horizontalCenter
            anchors.bottom: parent.bottom
            anchors.bottomMargin: 50
            font.pixelSize: 30
            color: "red"
            text: "Active area clicked!"
            opacity: 0
        }
        //左侧矩形由白变绿动画
        SequentialAnimation {
            id: leftClickedAnimation
            PropertyAction {
                target: leftRectangle
                property: "color"
                value: "white"
            }
            ColorAnimation {
                 target: leftRectangle
                 property: "color"
                 to: "green"
                 duration: 3000
             }
         }
         //右侧矩形从白变蓝动画
         SequentialAnimation {
             id: rightClickedAnimation
             PropertyAction {
                 target: rightRectangle
                 property: "color"
                 value: "white"
             }
             ColorAnimation {
                 target: rightRectangle
                 property: "color"
                 to: "blue"
                 duration: 3000
             }
         }
         //下方字体从完全透明变到不透明动画
         SequentialAnimation {
             id: activeClickedAnimation
             PropertyAction {
                 target: activeText
                 property: "opacity"
                value: 1
            }
            PropertyAnimation {
                target: activeText
                property: "opacity"
                to: 0
                duration: 3000
            }
        }
        // M2>>
        Connections {
            id: connections
            target: rightMouseArea
            onClicked: activeClickedAnimation.start();
        }
        // <<M2
        // M3>>
        states: [
            State {
                name: "left"
                StateChangeScript {
                    script: connections.target = leftMouseArea
                }
            },
            State {
                name: "right"
                StateChangeScript {
                    script: connections.target = rightMouseArea
                }
            }
        ]
        // <<M3
        Component.onCompleted: {
            state = "left";
        }
    }
    

    可以看到Connections中本来连接的是右侧矩形的点击区域, 但在Component.onCompleted中, 我们使用State(注意也只能使用State)修改了Connections的target属性, 将其target修改为左侧矩形的点击区域. 最终效果如下(下侧文字动画链接到了左侧点击区域):

    间接绑定(Binding Indirectly)

    有时我们需要运行时根据实际情况来绑定不同的target的某项属性, 可以使用Binding来实现间接绑定.

    代码如下:

    Rectangle {
        id: root
    
         600
        height: 400
    
        property int speed: 0   //参数speed
    
        SequentialAnimation {
            running: true
            loops: Animation.Infinite
    
            NumberAnimation { target: root; property: "speed"; to: 145; easing.type: Easing.InOutQuad; duration: 4000; }
            NumberAnimation { target: root; property: "speed"; to: 10; easing.type: Easing.InOutQuad; duration: 2000; }
        }
        // M1>>
        Loader {
            id: dialLoader
    
            anchors.left: parent.left
            anchors.right: parent.right
            anchors.top: parent.top
            anchors.bottom: analogButton.top
    
            onLoaded: {
                binder.target = dialLoader.item;    //根据Loader加载的对象不同, 将binder的target对象进行指定
            }
        }
    
        Binding {
            id: binder
            //target在此时是未知的, 且这里会报not defined错误, 但不影响运行. 也可以指定一个有效的target以避免语法错误提示, 但这不是必要的.
    
            property: "speed"   //绑定target的speed属性
            value: speed    //值从参数speed获取(参数speed的值会赋给target.speed属性, 从而影响target的显示).
        }
        // <<M1
        //左下方按钮
        Rectangle {
            id: analogButton
    
            anchors.left: parent.left
            anchors.bottom: parent.bottom
    
            color: "gray"
    
             parent.width/2
            height: 100
    
            Text {
                anchors.centerIn: parent
                text: "Analog"
            }
    
            MouseArea {
                anchors.fill: parent
                onClicked: root.state = "analog";
            }
        }
    
        //右下方按钮
        Rectangle {
            id: digitalButton
    
            anchors.right: parent.right
            anchors.bottom: parent.bottom
    
            color: "gray"
    
             parent.width/2
            height: 100
    
            Text {
                anchors.centerIn: parent
                text: "Digital"
            }
    
            MouseArea {
                anchors.fill: parent
                onClicked: root.state = "digital";
            }
        }
    
        state: "analog"
    
        // M3>>
        //状态
        states: [
            State {
                name: "analog"
                PropertyChanges { target: analogButton; color: "green"; }   //左侧按钮变绿
                PropertyChanges { target: dialLoader; source: "Analog.qml"; }   //加载QML界面
            },
            State {
                name: "digital"
                PropertyChanges { target: digitalButton; color: "green"; }  //右侧按钮变绿
                PropertyChanges { target: dialLoader; source: "Digital.qml"; }  //加载QML界面
            }
        ]
        // <<M3
    }
    

    代码运行效果如下:

    其他技巧

    绑定的破坏与恢复

    • 赋值会破坏绑定, 如果要恢复绑定可以调用Qt.binding, 代码如下:
    Button {
            onClicked: {
                item2.value = item1.value1 + 1 //这个是赋值表达式, 会破坏绑定
                item2.value = Qt.binding(function() { return item1.value1 + 1;}) //这个是绑定
            }
        }
    
    • 也可以使用Binding的条件绑定来控制绑定的破坏和恢复, 代码如下:
    property bool needBind: true
    Binding {
        target: item2
        property: "value2"
        value: item1.value1 + 1
        when: needBind
    }
    
    Button {
        onClicked: {
            needBind = false;   //绑定破坏
            item2.value = item1.value1 + 10; 
        }
    }
    Button {
        onClicked: {
            needBind = true;   //绑定恢复
        }
    }
    

    以上代码摘录自: <<QML book (ch14)>>

  • 相关阅读:
    Git: git tag 使用小结(给发布版本打标记,切换并修改某个历史版本)
    android: Android水波纹点击效果
    Flutter: 运行新项目报错
    FFmpeg编译:mac下编译iOS平台的FFmpeg库(支持armv7, arm64, i386, x86_64)
    Xcode: Xcode中Command Line Tools的安装方法
    win10: windows+E 改回打开我的电脑
    DialogFragment: DialogFragment的一些理解
    Android Studio: 查看SDK源代码
    HandlerThread: HandlerThread的理解
    Looper: Looper,Handler,MessageQueue三者之间的联系
  • 原文地址:https://www.cnblogs.com/linkyip/p/13298340.html
Copyright © 2011-2022 走看看