在QML中(至少直到版本5.6 1 ),一旦在JavaScript上下文中分配了新值,属性绑定就会被破坏:
Item {
property bool sourceBool: <some changing value e.g. from C++ code>
property bool boundBool: sourceBool
function reassignBool() {
boundBool = true;
}
}
调用reassignBool
后,无论boundBool
的状态如何,true
都将为sourceBool
。
我希望能够为不会破坏原始绑定的属性分配临时值;临时值将持续存在,直到触发与原始绑定关联的任何NOTIFY
信号,此时绑定属性将再次反映绑定计算的值。
作为示例用例,假设我有一个按钮,我不希望用户能够连续按两次,并根据一些规则启用或禁用:
MyButton {
id: onceOnlyButton
// Suppose the QML type `MyButton` provides a boolean property
// called `enabled` that greys out the button and prevents it from
// being clicked when `false`.
enabled: <condition1> && <scondition2>
onClicked: {
<schedule some asynchronous work>
}
}
假设,当点击该按钮时,<condition1>
将最终变为false
,以便该按钮最终被适当禁用 - - 但不是立即。
所以我想做以下的事情:
....
onClicked: {
enabled = false
<schedule some asynchronous work>
enabled = Qt.binding(function() {
return <condition1> && <condition2>
}
}
...但当然,一旦我重新建立绑定,由于condition1
尚未 成为false
,enabled
将成为再次true
。
我想我可以创建某种Connections
对象,将NOTIFY
与<condition1>
相关联的信号连接到一个可以调用Qt.binding
的处理程序,然后....我想,删除Connections
对象。但这似乎相当复杂和不优雅。
有没有办法确保enabled
立即设置为false
,然后重新绑定NOTIFY
<condition1>
信号<condition2>
只要发出任何信号,就tax
?
1 我不完全确定分配如何影响5.7中的绑定,但我知道assigning a value to a property does not automatically break the binding。因此,这可能只是在5.7中自动开箱即用。
答案 0 :(得分:1)
这对于使用QML Binding
类型来说应该是相当直接的,这对于临时覆盖绑定而不会破坏它非常有用(并且它自版本5.6之前就已存在!)
您需要一个可以在Binding类型的when
属性中使用的变量或属性。在下面的示例中,我使用了timer.running
,因为此处安排的异步工作只是一个计时器。
import QtQuick 2.7
import QtQuick.Controls 2.0
ApplicationWindow {
visible: true
width: 640
height: 480
property bool condition1: true
property bool condition2: true
Button {
id: onceOnlyButton
enabled: condition1 && condition2
Binding on enabled {
when: timer.running
value: false
}
onClicked: {
timer.start()
}
text: "onceOnlyButton"
}
// stuff below is just for demonstration
Button {
anchors.left: onceOnlyButton.right
text: "toggle Condition1\n(to prove binding still intact)"
onClicked: condition1 = !condition1
}
Timer {
id: timer
interval: 2000
running: false
repeat: false
onTriggered: condition1 = false
}
}
如果您没有变量,可以用来确定异步工作是否仍在继续(例如我的timer.running
),那么您需要创建一个变量,如下面的属性{{1} }。这使它看起来更复杂,所以我们将它包装在一个新的可重用组件中:
forceButtonDisable
import QtQuick 2.7
import QtQuick.Controls 2.0
Item {
id: control
property alias text: button.text
property bool enabled
property bool forceButtonDisable: false
signal clicked()
onEnabledChanged: forceButtonDisable = false
width: button.implicitWidth
height: button.implicitHeight
Button {
id: button
width: control.width
height: control.height
enabled: control.enabled
Binding on enabled {
when: control.forceButtonDisable
value: false
}
onClicked: {
control.forceButtonDisable = true
control.clicked()
}
}
}