用于更新属性的 QML 条件逻辑
Posted
技术标签:
【中文标题】用于更新属性的 QML 条件逻辑【英文标题】:QML condition logic for updating a property 【发布时间】: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)
【问题讨论】:
【参考方案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'
]
【讨论】:
以上是关于用于更新属性的 QML 条件逻辑的主要内容,如果未能解决你的问题,请参考以下文章