Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. [solved] When it is better to use a user event vs user signal for QStateMachine transitions?
QtWS25 Last Chance

[solved] When it is better to use a user event vs user signal for QStateMachine transitions?

Scheduled Pinned Locked Moved General and Desktop
4 Posts 2 Posters 1.7k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • T Offline
    T Offline
    TrueQtUser
    wrote on last edited by
    #1

    I am just starting a project where I will use a QStateMachine. It appears I will have several transitions I will want to trigger myself, unrelated to any existing signal or event. My question is what are the reasons to prefer custom signals which I create vs custom events which I create. I'm looking for the general pros and cons since I haven't designed all the states and transitions yet, but here is one example to make it clearer.

    To use a custom signal I think it would look something like this:
    @
    // MainWindow code
    QStateMachine stateMachine;
    // Setup custom state so it can trigger the transition when it wants.
    State* stateSplashScreen = new SplashScreenState(&stateMachine);
    State* stateSleep = new State(&stateMachine);
    // Setup transition using a signal.
    stateSplashScreen->addTransition(stateSplashScreen, SIGNAL(finishedNoUser()), stateSleep);
    // Start state machine
    stateMachine.start();

    // Custom state description
    class SplashScreenState : public State
    {
    Q_OBJECT
    public:
    explicit SplashScreenState(QState parent = 0);
    signals:
    void finishedNoUser();
    protected slots:
    void exit();
    protected:
    virtual void onEntry(QEvent
    event);
    protected:
    QTimer m_stateTimer;
    };

    // Custom state implimentation
    SplashScreenState::SplashScreenState(QState *parent) :
    State(parent),
    m_stateTimer(this)
    {
    // Set up state timer to reach exit() when time has expired.
    m_stateTimer.setInterval(1000);
    m_stateTimer.setSingleShot(true);
    connect(&m_stateTimer, SIGNAL(timeout()), this, SLOT(exit()));
    }

    // Start timer upon entry to state.
    void SplashScreenState::onEntry(QEvent* event)
    {
    Q_UNUSED(event);
    m_stateTimer.start();
    }

    void SplashScreenState::exit()
    {
    // Some complicated code that selectively if we
    // really want to exit, or do something more in this state.
    // Decides we want to leave in a way that will go to sleepState.
    emit finishedNoUser();
    }
    @
    To use a custom signal I think it would look something like this:
    @
    // MainWindow code
    QStateMachine stateMachine;
    // Setup custom state so it can trigger the transition when it wants.
    State* stateSplashScreen = new SplashScreenState(&stateMachine);
    State* stateSleep = new State(&stateMachine);
    // Setup transition using an event.
    FinishedNoUserTransition* finishedNoUserTransition = new FinishedNoUserTransition();
    finishedNoUserTransition->setTargetState(stateSleep);
    stateSplashScreen->addTransition(finishedNoUserTransition);
    // Start state machine
    stateMachine.start();

    // Custom event description
    class FinishedNoUserEvent : public QEvent
    {
    public:
    FinishedNoUserEvent() : QEvent(QEvent::Type(QEvent::User + 1) )
    {}
    };
    // Custom transition description
    class FinishedNoUserTransition : public QAbstractTransition
    {
    public:
    FinishedNoUserTransition() {}
    protected:
    virtual bool eventTest(QEvent *e)
    {
    return (e->type() == QEvent::User + 1);
    }
    virtual void onTransition(QEvent *)
    {}
    };

    // Custom state description
    class SplashScreenState : public State
    {
    Q_OBJECT
    public:
    explicit SplashScreenState(QState parent = 0);
    protected slots:
    void exit();
    protected:
    virtual void onEntry(QEvent
    event);
    protected:
    QTimer m_stateTimer;
    };

    // Custom state implimentation
    SplashScreenState::SplashScreenState(QState *parent) :
    State(parent),
    m_stateTimer(this)
    {
    // Set up state timer to reach exit() when time has expired.
    m_stateTimer.setInterval(1000);
    m_stateTimer.setSingleShot(true);
    connect(&m_stateTimer, SIGNAL(timeout()), this, SLOT(exit()));
    }

    // Start timer upon entry to state.
    void SplashScreenState::onEntry(QEvent* event)
    {
    Q_UNUSED(event);
    m_stateTimer.start();
    }

    void SplashScreenState::exit()
    {
    // Some complicated code that selectively if we
    // really want to exit, or do something more in this state.
    // Decides we want to leave in a way that will go to sleepState.
    machine()->postEvent(new FinishedNoUserEvent());
    }
    @

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi and welcome to devnet,

      The selection of one versus the other is essentially a question of which one describes the best the reason for the transition e.g. if you were using your state machine to model a hardware device, you would probably use both but for different purpose like you have a the doubleClicked signal where it make sense but on standard widget you have to handle it through an event.

      Hope it helps

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • T Offline
        T Offline
        TrueQtUser
        wrote on last edited by
        #3

        Thanks for the ideas. Here's what I've noticed:

        For QStateMachines it "appears":http://qt-project.org/doc/qt-4.8/statemachine-api.html#events-transitions-and-guards both end up as events. So, there is no reason to choose one over the other for control flow.

        The code (see original posting) for signals looks simpler to me.

        Signals probably work best for "simple argument types":http://qt-project.org/doc/qt-4.8/signalsandslots.html#signals.

        So, I think I'll mainly use signals for my internally generated transition triggers, unless I need to pass complex data with them.

        1 Reply Last reply
        0
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #4

          You're welcome !

          If that answers your question, please update the thread title prepending [solved] so other forum users may know a solution has been found :)

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          1 Reply Last reply
          0

          • Login

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • Users
          • Groups
          • Search
          • Get Qt Extensions
          • Unsolved