I have two widgets that can be checked, and a numeric entry field that should contain a value greater than zero. Whenever both widgets have been checked, and the numeric entry field contains a value greater than zero, a button should be enabled. I am struggling with defining a proper state machine for this situation. So far I have the following:
Qt Code:
  1. QStateMachine *machine = new QStateMachine(this);
  2.  
  3. QState *buttonDisabled = new QState(QState::ParallelStates);
  4. buttonDisabled->assignProperty(ui_->button, "enabled", false);
  5.  
  6. QState *a = new QState(buttonDisabled);
  7. QState *aUnchecked = new QState(a);
  8. QFinalState *aChecked = new QFinalState(a);
  9. aUnchecked->addTransition(wa, SIGNAL(checked()), aChecked);
  10. a->setInitialState(aUnchecked);
  11.  
  12. QState *b = new QState(buttonDisabled);
  13. QState *bUnchecked = new QState(b);
  14. QFinalState *bChecked = new QFinalState(b);
  15. employeeUnchecked->addTransition(wb, SIGNAL(checked()), bChecked);
  16. b->setInitialState(bUnchecked);
  17.  
  18. QState *weight = new QState(buttonDisabled);
  19. QState *weightZero = new QState(weight);
  20. QFinalState *weightGreaterThanZero = new QFinalState(weight);
  21. weightZero->addTransition(this, SIGNAL(validWeight()), weightGreaterThanZero);
  22. weight->setInitialState(weightZero);
  23.  
  24. QState *buttonEnabled = new QState();
  25. buttonEnabled->assignProperty(ui_->registerButton, "enabled", true);
  26.  
  27. buttonDisabled->addTransition(buttonDisabled, SIGNAL(finished()), buttonEnabled);
  28. buttonEnabled->addTransition(this, SIGNAL(invalidWeight()), weightZero);
  29.  
  30. machine->addState(registerButtonDisabled);
  31. machine->addState(registerButtonEnabled);
  32. machine->setInitialState(registerButtonDisabled);
  33. machine->start();
To copy to clipboard, switch view to plain text mode 
The problem here is that the following transition:
Qt Code:
  1. buttonEnabled->addTransition(this, SIGNAL(invalidWeight()), weightZero);
To copy to clipboard, switch view to plain text mode 
causes all the child states in the registerButtonDisabled state to be reverted to their initial state. This is unwanted behaviour, as I want the a and b states to remain in the same state.

How do I ensure that a and b remain in the same state? Is there another / better way this problem can be solved using state machines?

Note. There are a countless (arguably better) ways to solve this problem. However, I am only interested in a solution that uses a state machine. I think such a simple use case should be solvable using a simple state machine, right?