繁体   English   中英

Qt QStateMachine 同步问题:未在启动信号上设置初始 State

[英]Qt QStateMachine Sync Problems: Initial State not set on Started Signal

所以我试图了解 Qt 的 QStateMachine 的问题,我希望有人能帮助解释为什么会这样。 我对 QStateMachine 的基本理解非常感兴趣,而不仅仅是修复。

首先考虑状态为 A、B 和事件 1 的 state 机器。事件 1 将您从 A 带到 B。A 是初始的 state。

具体来说,这是为了维护邻居。 在设备 XI 中收到邻居 Y 打招呼的消息。 这导致邻居 X 到 malloc 一个邻居 state 机器为这个新邻居 Y。这使得邻居 state 机器然后调用 QStateMachine::start();

现在,在这台 state 机器启动后,我需要继续处理这条问候消息。 所以起初我在做:

QStateMachine::start( ) ;
emit event 1 ;

我的理解是这是行不通的,因为 start 是一个异步调用,因此 state 机器在启动完成后才处于初始启动状态。 这引出了我的第一个问题。

1) 所以 state 机器启动被放置在 qapp 事件队列中,但也没有发出异步调用? 事件 1 不会在开始后放入事件队列中,所以这是否意味着我们将在初始 state 中? 或者 emit 不是异步调用?

认为这是问题所在,我通过将 function 连接到 state 机器启动信号来稍微更改我的代码。 然后,如果 state 机器未启动,我更改代码以对事件进行排队,并在调用启动信号后处理此待处理事件队列(并将它们发送到 state 机器)。

好吧,当我开始信号时,最初的 state 仍然没有设置。 例如 QStateMachine::configuration().contains(initialstate) == false。 这引出了我的第二个也是更大的问题。

2)为什么发出启动信号时我不在初始state中。

这里的事件顺序是:

  1. 创建 state 机器
  2. 设置初始 state
  3. 启动state机器
  4. 接收事件 1
  5. 由于未启动队列事件 1
  6. 开始信号 rxed
  7. 处理事件 1
  8. 由于未知 state 什么都不做
  9. 接收事件 1
  10. 处理事件 1
  11. 现在在 state A. 过渡到 state B.

顺序应该是:

  1. 创建 state 机器
  2. 设置初始 state
  3. 启动state机器
  4. 接收事件 1
  5. 由于未启动队列事件 1
  6. 开始信号 rxed
  7. 处理事件 1
  8. 现在是 state A. 过渡到 state B.
  9. 接收事件 1
  10. 处理事件 1
  11. 现在是 state B.什么都不做。

或者更好的活动我希望我不必排队参加活动。 我希望我能这样做:

  1. 创建 state 机器
  2. 设置初始 state
  3. 启动state机器
  4. 接收事件 1
  5. 处理事件 1
  6. 现在是 state A. 过渡到 state B.
  7. 接收事件 1
  8. 处理事件 1
  9. 现在是 state B.什么都不做。

转换信号仅在 state 更改后连接(在QStateMachinePrivate::registerSignalTransition中)并且连接不是排队连接:

bool ok = QMetaObject::connect(sender, signalIndex, signalEventGenerator,
                                   signalEventGenerator->metaObject()->methodOffset());

对于要接收的“事件 1”,机器必须已经处于对该信号做出反应的 state 中。 即使它是排队连接,插槽也会排队,但只有在收到信号后才会排队,因为此时还没有连接。

要解决您的问题,您可以在发出信号之前等待机器处于“状态 A”:

machine->start();
qApp->processEvents();
emit event1();

或者你可以延迟信号发射并在其他已经排队的操作之后排队:

machine->start();
QTimer::singleShot(0, emitter, SIGNAL(event1()));
// or
QMetaObject::invokeMethod(emitter, "event1", Qt::QueuedConnection);

started信号在设置初始 state 之前发出(根据源代码),如果您在设置任何 state 之前要进行初始化,这会很有帮助。 如果需要等待初始的 state,可以使用信号QState::entered

暂无
暂无

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

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