Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use the argument of a Signal in QML StateMachine during SignalTransition

Tags:

qt

qt-signals

qml

I have a C++ class and I made it possible to be able to create it in QML. Then I have a signal in QML which has an argument representing this object. I am using the QtQml.StateMachine and I am catching triggered signals with SignalTransition. I want to be able to set my signals argument to the next state when the SignalTransition triggers. In code:

This is how my signal looks like in Model.qml:

signal mySignal(CustomObject customObject)

My signal transitioning code in State.qml:

import QtQml.StateMachine 1.0 as SM

// SM.State { ...

Model {
    id: model
    // ...
}

SM.SignalTransition {
    targetState: nextState
    signal: model.mySignal
    onTriggered: console.log(customObject) // error here
}

// ... } 

I get the following error: ReferenceError: customObject is not defined. When I am emitting the signal I pass my customObject as an argument for the signal.

like image 821
Silex Avatar asked Oct 18 '22 12:10

Silex


2 Answers

This is a bit of a hack, but the guard is passed the signal's parameters. The guard is an expression which is evaluated to see if it's true (and if so, the transition applies) but there's nothing stopping you running extra code in there. So:

State {
    targetState: nextState
    signal: model.mySignal
    guard: {
        // here, customObject is available, because it was an arg to the signal
        // so, stash it away somewhere where you can get at it later
        root.currentCustomObject = customObject;
        // and explicitly return true, so that this guard passes OK and
        // then the transition actually happens
        return true;
    }
}
like image 146
sil Avatar answered Jan 04 '23 06:01

sil


One approach would be to have the mySignal handler set a property that can be summarily accessed by the less-flexible SignalTransition, like so:

Model {
    id: model
    property CustomObject currentObj
    onMySignal: currentObj = customObject
}

SM.SignalTransition {
    targetState: nextState
    signal: model.currentObjChanged
    onTriggered: console.log(model.currentObj)
}

Hacky and not tested, but might be acceptable for this case.

like image 45
Jonas G. Drange Avatar answered Jan 04 '23 05:01

Jonas G. Drange