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

Qt 用于更新属性的QML条件逻辑,qt,qml,logic,conditional-statements,Qt,Qml,Logic,Conditional Statements,我正在搜索一个逻辑,以便根据一些不同的条件更改图像源属性 我创建了一个小示例,其中包含三个条件和由这些条件构建的三个需求 如果某个需求处于活动状态,我希望在图像区域中看到它的图片。 如果某个需求未激活,我不希望在图像区域中看到它的图像。 如果两个需求同时处于活动状态,则可以只看到其中一个 我对代码有问题,因为如果一个需求不活跃,而另一个需求同时活跃,最后一个需求将控制内容。但我希望在显示图像时比不显示图像时有更高的优先级 有什么常见的方法可以解决这个问题吗 我有以下代码: main.qml: i

我正在搜索一个逻辑,以便根据一些不同的条件更改图像源属性

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

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

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

有什么常见的方法可以解决这个问题吗

我有以下代码:

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

我不认为这是一个合理的方法,因为绑定表达式求值的顺序是不明确的。

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

通过您的
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使用率

但是如果您坚持使用当前的方法,您可以使用
绑定
元素,这些元素可以在属性时使用它们的
自动打开或关闭


最后,您也可以使用QML自己的,尽管对于这样一个微不足道的情况来说,这可能会有点过头。

根据dtech的评论,我创建了一个使用状态的示例。这和预期的一样,我能够将状态(需求)从main.qml(布局)中分离出来。谢谢

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

谢谢dtech!实际上,一个需求(StateObserver对象)要复杂得多,我最多有50个。我认为将所有内容直接放在Image source属性中可能会变得不清楚。我认为绑定可能正是我所需要的。不幸的是,绑定与我上面发布的方法存在相同的问题。如果绑定处于非活动状态,则图像将包含绑定的最后一个内容,但如果没有绑定处于活动状态,则我希望将图像源返回到“”。然后,您应该在源{value::;when:someBooleanExpressionThat true上添加绑定
binding when没有其他绑定处于活动状态}
-类似于dtech绑定中的最后一行