Important: Please read the Qt Code of Conduct -

How to return to a previous state using QStateHistory with nested states?

  • Hello,

    I work on a state machine with QState.

    I have a problem about returning to a previous state with the class QHistoryState.

    Here is a diagram of the part that poses me problem:

    Diagram here

    For example I would like that when I use the interruption that allows to go from S13 to S3, when returning to the previous state, I return to S13 (the previous state).

    But because I have defined S11 as the initial state of S1, the state machine returns to S11.

    What is the best way to do that, knowing that I want to be able to do the same thing from S22 for example.

    [edit: Fixed image link SGaist]

  • Lifetime Qt Champion


    Can you show the code you use to create the state machine and manage the history state ? From my understanding of the class, it should return to the last child state it was in unless it never entered the parent state, in which case it will use the default that you set on it.

  • Hi,

    Here is the main part of the cpp file:

    #include "ui_mainwindow.h"
    MainWindow::MainWindow(QWidget *parent) :
        ui(new Ui::MainWindow)
        machine=new QStateMachine();
        s3 = new QState();
        s0 = new QState();
        s1 = new QState(s0);
        s2 = new QState(s0);
        s11 = new QState(s1);
        s12 = new QState(s1);
        s13 = new QState(s1);
        s21 = new QState(s2);
        s22 = new QState(s2);
        s23 = new QState(s2);
        s1h=new QHistoryState(s1);
        s2h=new QHistoryState(s2);
        s0h=new QHistoryState(s0);
        s11->addTransition(ui->pb_s12, SIGNAL(clicked()), s12);
        s12->addTransition(ui->pb_s13, SIGNAL(clicked()), s13);
        s13->addTransition(ui->pb_s11, SIGNAL(clicked()), s11);
        s21->addTransition(ui->pb_s22, SIGNAL(clicked()), s22);
        s22->addTransition(ui->pb_s23, SIGNAL(clicked()), s23);
        s23->addTransition(ui->pb_s21, SIGNAL(clicked()), s21);
        s0->addTransition(ui->pb_s3, SIGNAL(clicked()), s3);
        s3->addTransition(ui->pb_s3, SIGNAL(clicked()), s0h);
        s1->addTransition(ui->pb_s2, SIGNAL(clicked()), s2);
        s2->addTransition(ui->pb_s2, SIGNAL(clicked()), s1h);
        connect(s0, SIGNAL(entered()), this, SLOT(enteredS0()));
        connect(s0, SIGNAL(exited()), this, SLOT(exitedS0()));
        connect(s1, SIGNAL(entered()), this, SLOT(enteredS1()));
        connect(s1, SIGNAL(exited()), this, SLOT(exitedS1()));
        connect(s11, SIGNAL(entered()), this, SLOT(enteredS11()));
        connect(s11, SIGNAL(exited()), this, SLOT(exitedS11()));
        connect(s12, SIGNAL(entered()), this, SLOT(enteredS12()));
        connect(s12, SIGNAL(exited()), this, SLOT(exitedS12()));
        connect(s13, SIGNAL(entered()), this, SLOT(enteredS13()));
        connect(s13, SIGNAL(exited()), this, SLOT(exitedS13()));
        connect(s2, SIGNAL(entered()), this, SLOT(enteredS2()));
        connect(s2, SIGNAL(exited()), this, SLOT(exitedS2()));
        connect(s21, SIGNAL(entered()), this, SLOT(enteredS21()));
        connect(s21, SIGNAL(exited()), this, SLOT(exitedS21()));
        connect(s22, SIGNAL(entered()), this, SLOT(enteredS22()));
        connect(s22, SIGNAL(exited()), this, SLOT(exitedS22()));
        connect(s23, SIGNAL(entered()), this, SLOT(enteredS23()));
        connect(s23, SIGNAL(exited()), this, SLOT(exitedS23()));
        connect(s3, SIGNAL(entered()), this, SLOT(enteredS3()));
        connect(s3, SIGNAL(exited()), this, SLOT(exitedS3()));

    When the machine leave s3, it always return to s11 or s21.

    I've uploaded the complete project here:

    Thanks for your help!

  • OK, I found what was wrong.

    I needed to set the history type with this function:


    from the documentation page of QHistoryState:

Log in to reply