(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 through

    I'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.0

    Rectangle {
    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.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.