Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 与qstate机器的同步问题_C++_Qt_Qt5_State Machine - Fatal编程技术网

C++ 与qstate机器的同步问题

C++ 与qstate机器的同步问题,c++,qt,qt5,state-machine,C++,Qt,Qt5,State Machine,我的程序中有一个QStateMachine的实例。我在它的构造函数中配置它的状态、转换和初始状态。当然,我从构造函数开始 this->stateA = new StateA(this); this->stateB = new StateB(this); this->stateA->addTransition(this, &Machine::foo, this->stateB); this->setInitialState(this->stateA

我的程序中有一个
QStateMachine
的实例。我在它的构造函数中配置它的状态、转换和初始状态。当然,我从构造函数开始

this->stateA = new StateA(this);
this->stateB = new StateB(this);
this->stateA->addTransition(this, &Machine::foo, this->stateB);
this->setInitialState(this->stateA);
this->start();
// At this point the machine is still not in the stateA
我面临的问题是,在
start()
完成执行之前,机器不会移动到初始状态。这导致了一个问题,即在进入初始状态之前发出一个信号
foo
,该信号本应将机器从初始状态移动到另一个状态

Machine* machine = new Machine(); 
// start() was already called here but the machine is still not in the initial state
machine->foo();
// Signal is emitted here (It also may not be emitted. This is not an unconditional transition). But the machine is still not in the initial state and the transition does not happen.
// ...
// Here the machine enters the initial state...

如何确保机器在构造时处于初始状态?

状态机是异步的,由事件循环驱动。您没有理由在启动时使用该信号将机器移动到另一个状态。目前,您希望在启动时以及在发出
foo
时从
stateA
转换到
stateB

  • 请记住,连接的目标可以是信号或插槽。您可以将状态机的
    started
    信号连接到
    foo
    信号。这样,当机器启动并处于初始状态时,将发出
    foo

  • 如果您不关心
    foo
    信号,则可以设置转换以直接在机器的
    启动
    信号上触发

  • 如果您总是想从
    stateA
    转换到
    stateB
    ,即使在机器启动并以某种方式重新输入
    stateA
    后的一段时间,您也可以无条件地从初始状态转换到
    stateB
    。机器在输入
    stateA
    后将离开,然后自动输入
    stateB


  • 从上一个解决方案开始检查解决方案,如果您需要一个不太通用的解决方案,请向上移动。

    您可以通过在构造函数中创建如下事件循环,确保机器在构造时处于初始状态:

    // ...
    this->start();
    QEventLoop* eventLoop = new QEventLoop(this);
    QObject::connect(
        this, &Machine::started,
        eventLoop, &QEventLoop::quit
    );
    eventLoop->exec();
    

    谢谢你的回答。我可能没有很好地描述我想要实现的目标。我不想总是在机器启动时执行从
    A
    B
    的转换<代码>机器->foo()根据某些条件,可能会或可能不会发出信号。我希望转换只在信号发出后执行。据我所知,唯一的解决办法是等待机器进入初始状态(等待机器发出
    初始化的
    信号),然后才对其执行任何操作。@Kolyunya这不是一个解决办法,这是你一直应该做的。异步思考。不要“等待”机器启动,只要在机器启动时运行一些代码即可。这是通过将
    started
    信号连接到插槽或函子来完成的。