EDIT: it's a QT Bug https://bugreports.qt.io/browse/QTBUG-86695
--
The problem with the 'when' clause enabling the default unnamed state "" in some situations, even if it does not appear in the list of is not specific to Button. If you have more than one state and transitions between states, you usually can't use the when clause anymore until this bug is fixed.
If you have only two stated you may avoid the unnamed "" default state as follows:
- put the default state at the end of the state array and
- specify
when: 1 == 1 (if you do not need to support QT 5.12 you may also write when: true here).
To see how this workaround fixes the OPs problem consider the following example (deliberately not using Button to also show that the problem is much more general and is not related to the released state of Button):
Item {
id: item
anchors.fill: parent
property bool toggle
Button {
anchors.fill: parent
onClicked: item.toggle = ! item.toggle
}
states: [
State {
name: "true"
when: item.toggle
},
State {
name: "false"
when: ! item.toggle
}
]
onStateChanged: {
console.log("state:", state, "toggle:", toggle)
}
}
In QT 5.12.9 clicking twice produces the following output (first line on startup)
qml: state: false toggle: false
qml: state: true toggle: true
qml: state: false toggle: false
In QT 5.15.2 clicking twice produces the following output (first line on startup)
qml: state: false toggle: false
qml: state: toggle: true
qml: state: true toggle: true
qml: state: false toggle: false
So switching form toggle: false to toggle: true goes through the "" default state in QT 5.15.2 rather than directly to the "true" state. If you change the sequence of state definitions, the other state change goes through "". It looks like there is a moment when the when clause of the "false" state is false, but the when clause of the "true" state is not true yet.
In QT 5.15.2 specifying when: true on the "false" state works, i.e. the states toggle as in QT 5.12.9 and the default unnamed "" state is never applied. But this workaround produces an error (Invalid property assignment: unsupported type "QQmlBinding*") in QT 5.12.9 (which I also need to support). This error is avoided by when: 1 == 1. So here is my final workaround:
Item {
id: item
anchors.fill: parent
property bool toggle
Button {
anchors.fill: parent
onClicked: item.toggle = ! item.toggle
}
states: [
State {
name: "true"
when: item.toggle
},
State {
name: "false"
when: 1 == 1
}
]
onStateChanged: {
console.log("state:", state, "toggle:", toggle)
}
}