【问题标题】:QML condition logic for updating a property用于更新属性的 QML 条件逻辑
【发布时间】:2018-11-25 09:36:17
【问题描述】:

我正在寻找一种逻辑,以便根据一些不同的条件更改图像源属性。

我创建了一个小示例,其中包含三个条件和三个由这些条件构建的要求。

如果某个需求处于活动状态,我想在图像区域中查看它的图片。 如果一个需求不活跃,我不想在图像区域看到它的图像。 如果两个需求同时处于活动状态,则可以只查看其中一个。

我的代码有问题,因为如果一个需求处于非活动状态,而另一个需求同时处于活动状态,最后一个需求将控制内容。但我希望显示图像比不显示图像具有更高的优先级。

有没有常见的方法来解决这个问题?

我有以下代码:

main.qml:

import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.0

ApplicationWindow {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    property bool condition1: false
    property bool condition2: false
    property bool condition3: false

    Image{
        id: image
        anchors.top: parent.top
        anchors.horizontalCenter: parent.horizontalCenter
        width: 120
        height: 120
        source: ""
    }

    Row {
        anchors.top: image.bottom
        anchors.horizontalCenter: parent.horizontalCenter

        Button {
            id: button1
            text: "Condition1 = " + condition1
            onClicked: condition1 = !condition1
        }
        Button {
            id: button2
            text: "Condition2 = " + condition2
            onClicked: condition2 = !condition2
        }
        Button {
            id: button3
            text: "Condition3 = " + condition3
            onClicked: condition3 = !condition3
        }
    }

    StateObserver{
        condition: condition1 && condition2 && condition3
        bitmap: "Images/1.png"
        target: image
    }
    StateObserver{
        condition: !condition1 && condition2 && condition3
        bitmap: "Images/2.png"
        target: image
    }
    StateObserver{
        condition: !condition1 && !condition2 && condition3
        bitmap: "Images/3.png"
        target: image
    }
}

StateObserver.qml

import QtQuick 2.0

Item {

    property bool condition

    property string bitmap

    property var target

    onConditionChanged: {
        if (condition){
        target.source = bitmap
        }
        else {
            target.source = ""
        }

        console.log("Change bitmap: " + bitmap)
    }
}

【问题讨论】:

    标签: qt qml logic conditional-statements


    【解决方案1】:

    我不认为这是一个合理的方法,因为绑定表达式评估的顺序是未指定的。

    我要做的是有一个点来评估所有可能的组合并使用其结果来装配其余属性。

    通过您的StateObserver,您基本上是在引入不必要的复杂性。您也不必考虑所有可能的状态配置。

    你可以简单地:

      Image {
        id: image
        //...
        source: {
          if (condition1 && condition2 && condition3) return "Images/1.png"
          else if (!condition1 && condition2 && condition3) return "Images/2.png"
          else if (!condition1 && !condition2 && condition3) return "Images/3.png"
          else return ""
        } 
      }
    

    这意味着更少的代码和更少的对象,这意味着更低的内存和 CPU 使用率。

    但是,如果您坚持使用当前方法,则可以使用 Binding 元素,这些元素可以使用 when 属性自动打开或关闭。

    最后,您也可以使用 QML 自己的 state machine,尽管对于这样一个琐碎的情况,这将是矫枉过正。

    【讨论】:

    • 感谢 dtech!实际上,一个需求(StateObserver-Object)会更复杂,我最多需要 50 个。我认为将所有内容直接放在 Image-source 属性中可能会变得不清楚。我认为绑定可能正是我所需要的。
    • 不幸的是,绑定与我上面发布的方法有同样的问题。如果绑定不活动,图像将包含绑定的最后内容,但我想让图像源回到“”,以防绑定不活动。
    • 那么你应该添加一个绑定 Binding on source { value: ""; when: someBooleanExpressionThatIsTrueWhenNoOtherBindingIsActive} - 类似于 dtech 绑定中的最后一行
    【解决方案2】:

    根据 dtech 的评论,我创建了一个使用状态的示例。这像预期的那样工作,我能够将状态(要求)与 main.qml(布局)分开。谢谢!

    main.qml:

    import QtQuick 2.7
    import QtQuick.Controls 2.0
    import QtQuick.Layouts 1.0
    
    ApplicationWindow {
        id: mainApp
        visible: true
        width: 640
        height: 480
        title: qsTr("Hello World")
    
        property bool condition1: false
        property bool condition2: false
        property bool condition3: false
    
        Image{
            id: image
    
            anchors.top: parent.top
            anchors.horizontalCenter: parent.horizontalCenter
            width: 120
            height: 120
    
            Img_StateList{
                container: image
            }
        }
    
    
        Row {
            anchors.top: image.bottom
            anchors.horizontalCenter: parent.horizontalCenter
    
            Button {
                id: button1
                text: "Condition1 = " + condition1
                onClicked: condition1 = !condition1
            }
            Button {
                id: button2
                text: "Condition2 = " + condition2
                onClicked: condition2 = !condition2
            }
            Button {
                id: button3
                text: "Condition3 = " + condition3
                onClicked: condition3 = !condition3
            }
        }
    }
    

    Img_StateList.qml:

    import QtQuick 2.0
    
    Item {
        property Image container;
        state: "default"
        states: [
            State {
                name: "default"
                PropertyChanges {
                    target: container
                    source: ''
                }
            },
            State {
                name: "Img1"
                when: condition1 && condition2 && condition3
                PropertyChanges {
                    target: container
                    source: 'Images/1.png'
                }
            },
            State {
                name: "Img2"
                when: !condition1 && condition2 && condition3
                PropertyChanges {
                    target: container
                    source: 'Images/2.png'
                }
            },
            State {
                name: "Img3"
                when: !condition1 && !condition2 && condition3
                PropertyChanges {
                    target: container
                    source: 'Images/3.png'
                }
            }
        ]
    }
    

    【讨论】:

      猜你喜欢
      • 2017-08-06
      • 1970-01-01
      • 2023-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多