Qt signal transition on parent state overriden by child state

Viewed 106

In my QStateMachine, I have a QState parent that has several children states child1, child2 and child3. I want all children to have a common response to the signal MyStruct::mySignal(). However, I also want child1 to do something more on that signal. I thought of creating a QSignalTransition on the parent with the common response, and creating another one with the specific behavior for child1 (see the code below).

struct MyStruct {
  Q_OBJECT

  Q_SIGNAL void mySignal();

  void commonResponse() {
    std::cout << "Common" << std::endl;
  }

  void specificResponse() {
    std::cout << "Specific" << std::endl;
  }
};

QState* parent = new QState();
QState* child1 = new QState(parent);
QState* child2 = new QState(parent);
QState* child3 = new QState(parent);

MyStruct myStruct;

QSignalTransition* commonTransition = new QSignalTransition(&myStruct, &MyStruct::mySignal);
parent->addTransition(commonTransition);
connect(commonTransition , &QAbstractTransition::triggered, &myStruct, &MyStruct::commonResponse);

QSignalTransition* specificTransition = new QSignalTransition(&myStruct, &MyStruct::mySignal);
child1->addTransition(specificTransition);
connect(specificTransition, &QAbstractTransition::triggered, &myStruct, &MyStruct::specificResponse);

However with this code, if I am currently in state child1 and a MyStruct::mySignal is emitted, then it will only output Specific. Is it possible to get the expected behavior of printing both Common and Specific while keeping the code clarity? (without adding a duplicate MyStruct::mySignal for the specific case, or having to "remember" to call commonResponse in specificResponse)

1 Answers

Here with your code, Conceptually you are overriding the inherited transition from the base class. child1->addTransition(specificTransition); overrides the parents addTransition.

Look into below documentation link and search for

A child state can override an inherited transition

https://doc.qt.io/qt-5/statemachine-api.html

As the parent transition is overridden, the only way you can achieve the expected behavior is by calling commonResponse from specificResponse

Or

Add the commonResponse behavior also in specificResponse, which is not a good idea in terms of maintenance.

Related