用于更新属性的QML条件逻辑

时间:2018-06-15 14:09:47

标签: qt qml logic conditional-statements

我正在搜索逻辑,因此根据某些不同的条件更改了Image源属性。

我创建了一个小例子,其中包含三个条件和三个条件。

如果要求有效,我想在图像区域看到它的图片。 如果要求未激活,我不希望在图像区域中看到其图像。 如果两个要求同时处于活动状态,则只能看到其中一个要求。

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

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

我有以下代码:

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)
    }
}

2 个答案:

答案 0 :(得分: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 ""
    } 
  }

代码少,对象少,意味着ram和cpu使用率降低。

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

最后,你也可以使用QML自己的state machine,尽管这样一个琐碎的案例会有点过分。

答案 1 :(得分:0)

通过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'
            }
        }
    ]
}