简体   繁体   English

Qt状态机:如何将单个转换与多个状态相关联

[英]Qt state machine: How to associate a single transition with multiple states

Question

I am currently working on a application using Qt state machine framework, my objective is to associate a single transition with multiple source states. 我目前正在使用Qt状态机框架开发应用程序,我的目标是将单个转换与多个源状态相关联。 The rationale for doing it is the signal causing the transition is independent of the source state, hence instead of multiple transitions (one for each source state) I thought it would be better to have one. 这样做的理由是导致转换的信号与源状态无关,因此不是多个转换(每个源状态一个),我认为最好有一个转换。 I am facing issues in acheiving the above mentioned through Qt.Details are demonstrated below with a test state machine. 我正面临着通过Qt实现上述问题的问题。下面用测试状态机演示详细信息。 (Below mentioned is an hypothetical state machine but I can aslo give some real world examples for such a use case). (下面提到的是一个假设的状态机,但我可以为这样一个用例提供一些真实世界的例子)。 Please suggest some effective ways for acheiving the mentioned objective. 请提出一些有效的方法来实现上述目标。

Code snippet where the problem lies 问题所在的代码片段

m_s1.addTransition(&m_Trans); // Adding transition to state S1
m_s2.addTransition(&m_Trans); // Adding the same transition to state S2
                              // As per Qt docs, it seems the ownership of thr transition will be transferred to s2 which is what is causing the problem.

在此输入图像描述

CState.hpp CState.hpp

class CState: public QState
{

public:

    /** Constructor */
    CState(std::string a_pStateName)
       :QState(nullptr),
        m_pStateName(a_pStateName)
    {

    }

    /** Overriding on entry */
    virtual void onEntry(QEvent *a_pEvent) Q_DECL_OVERRIDE
    {
        (void) a_pEvent;
        printf("State entry %s\n",m_pStateName.c_str());
    }

    ~CState() {}
     CState() {}
private:
    std::string  m_pStateName;
};

CTestMachine.hpp CTestMachine.hpp

class CTestStateMachine: public QObject
{
    Q_OBJECT

public:
    CTestStateMachine();
    ~CTestStateMachine() {};

private:
    QSignalTransition       m_Trans;
    CState                  m_s1;
    CState                  m_s2;
    CState                  m_s3;
    QStateMachine           m_TestMachine;
    QTimer                  m_Timer;

signals:
    void SourceIndependentSignal();

public slots:
    void TimetoInvokeTrans();


};

CTestMachine.cpp CTestMachine.cpp

#include <stdio.h>
#include <iostream>
#include <string>
using namespace std;

#include <QObject>
#include <QCoreApplication>
#include <QStateMachine>
#include <QState>
#include <QSignalTransition>
#include <QTimer>

#include "CState.hpp"
#include "CTestStateMachine.hpp"

void CTestStateMachine::TimetoInvokeTrans()
{
    printf("Emitting source independent signal\n");
    emit SourceIndependentSignal();
}

CTestStateMachine::CTestStateMachine():
    m_Trans(this, SIGNAL(SourceIndependentSignal())),
    m_s1("s1"),
    m_s2("s2"),
    m_s3("s3")
{
   /* Setup state machine */
   m_Trans.setTargetState(&m_s3);
   m_s1.addTransition(&m_Trans);
   m_s2.addTransition(&m_Trans);
   m_TestMachine.addState(&m_s1);
   m_TestMachine.addState(&m_s2);
   m_TestMachine.addState(&m_s3);
   m_TestMachine.setInitialState(&m_s1);
   m_TestMachine.start();
   printf("Started state machine\n");

   /* Trigger timer to make transitions */
   connect(&m_Timer, SIGNAL(timeout()), this, SLOT(TimetoInvokeTrans()));
   m_Timer.start(1000);
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    CTestStateMachine TestMachine;
    return a.exec();
}

You can move the transition on state entry. 您可以在状态输入上移动转换。

connect(m_state, &QState::entered, [m_state, m_tr]() -> void { m_state->addTransition(m_tr); });

Or just have a parent state keep the transition and set transition type to internal. 或者只是让父状态保持转换并将转换类型设置为内部。

QState *s = new QState(m_stateMachine);
QState *s1 = new QState(s);
QState *s2 = new QState(s);
QState *s3 = new QState(s);
QSignalTransition *sTr = new QSignalTransition(sender, SIGNAL(foobar), s);
sTr->setTargetState(s3);
sTr->setTransitionType(QAbstractTransition::InternalTransition);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM