(solved, kind of) MouseArea + GridView: how to change a state only when pressed == true
-
"This example of MouseArea + GridView":http://developer.qt.nokia.com/wiki/QML_gridview_mousearea_example has been very useful in additon of the official documentation for both items. However, there is a situation I'm not able to solve: how to apply a change only while the MouseArea is pressed, returning back to the previous situation when the finger is lifted?
This is what I have now:
@ State {
name: "wrongTap"
StateChangeScript {
script: {
chessboardGrid.model.set(index, {squareColor: "red"})
}
}@This paints the wrong square tapped in red, but ideally the squareColor should go back to "transparent" automatically.
@when: squareMouseArea.pressed === true@
doesn't work here. I have also tried to do this throughI'm also trying to set 'if' conditions inside the script but I'm not finding the right instructions either. Any hints?
-
Hi,
The problem here is that QML's state framework doesn't know how to "undo" (or reverse) a StateChangeScript when returning to the base state.
Assuming the original square color was green, adding the following state should make it return to green after exiting "wrongTap".
@
State {
name: ""
StateChangeScript {
script: chessboardGrid.model.set(index, {squareColor: "green"})
}
}
@You might also want to consider making these changes local to the delegate, rather than writing to the model, in which case you could use PropertyChanges to make the changes, and the reverse should automatically work. e.g. something like:
@
Rectangle {
id: square
states: State {
name: "wrongTap"
PropertyChanges {
target: square
color: "red"
}
}
}
@Regards,
Michael -
I already tried these approaches but the problem seems to be that, at least in the "context":https://gitorious.org/testdef/testdef/blobs/master/testdef/qml/OnlineBoard.qml of my humble app, the delegates remain in the same state even after the finger stops pressing the MouseArea. This is why in your two examples the square will remain "red" until a instruction changes explicitly the state, or the color back to "transparent".
I'm thinking of using another approach: activate a short animation turning the square red and then transparent again. This way visually it won't matter whether the state is still wrongTap or not. This will be my first QML animation, wish me good luck. :)
-
I don't know if this is the right solution but at least it works for my case (indicating a wrong tap with a brief red signal on a chess board square):
@ Component {
id: chessboardGridDelegate
Rectangle {
id: squareDelegate
width: 60
height: 60
color: squareColor
SequentialAnimation on color {
id: wrongTapAnimation
running: false
ColorAnimation { from: "red"; to: "red"; duration: 50 }
ColorAnimation { from: "red"; to: "transparent"; duration: 200; easing.type: Easing.OutQuart }
}...
State { name: "wrongTap" extend: 'cleaningSquares' PropertyChanges { target: wrongTapAnimation running: true } }@
-
[quote author="qgil" date="1312987069"]I already tried these approaches but the problem seems to be that, at least in the "context":https://gitorious.org/testdef/testdef/blobs/master/testdef/qml/OnlineBoard.qml of my humble app, the delegates remain in the same state even after the finger stops pressing the MouseArea. This is why in your two examples the square will remain "red" until a instruction changes explicitly the state, or the color back to "transparent".[/quote]
Hmm, that's odd. In general, if using a when clause, you should be automatically returned to the base state when the when clause becomes false, as demonstrated in the following example:
@
import QtQuick 1.0Rectangle {
id: square
width: 400; height: 400
color: "green"
states: State {
name: "wrongTap"
when: ma.pressed
PropertyChanges {
target: square
color: "red"
}
}MouseArea { id: ma anchors.fill: parent }
}
@Does the above work correctly for you?
Given the complexity of your delegate, you might also find STATECHANGE_DEBUG helpful -- you can set this environment variable to 1 to see information on state changes printed to the console.
Regards,
Michael -
Maybe the problem is that I'm using "onClicked:" instead of @press@. This works for me since in the cases other than a wrongTap I do want to keep the status: pieceSelected, pieceMoving... Sorry if I didn't mention this little details before and this happens to be the cause of my original trouble.
Anyway, triggering a ColorAnimation starting and finishing in transparent is working perfectly.