4

QStateMachine の使用法、特に遷移をトリガーするユーザー イベントの処理を理解しようとしています。さらに、ガードを実装する最良の方法を理解したいと思っています。以下にステートマシンを描きました。これはほとんどシーケンシャルであり、ステート マシンの良い例ではありませんが、QProcess 呼び出しの結果を待っている間に遅延があるため、ブロックしないという目的には役立ちます。これらの遅延は、代わりにタイムアウト イベントとして非同期に処理されます。

ステート マシンは、起動時に rndis 接続がないと想定し、定期的に長い一連のイベントを実行して接続を確認します。接続が検出されると、短いチェックが定期的に実行され、まだ接続されていることを確認し、そうでない場合は長いチェックの実行に戻ります。

これは不完全な基本的なセットアップ コードです。

// Set up state machine.  Do this so that checking for presence
// is non-blocking.  Delays are handled by framework.
//
QState* detected = new QState();
QState* notDetected = new QState();
QState* waitForIfDown = new QState();
QState* waitForCdcEther = new QState();

QEvent* timeout = new QEvent(QEvent::Type(EVENT_TIMEOUT));

m_machine.addState(detected);
m_machine.addState(notDetected);
m_machine.addState(waitForIfDown);
m_machine.addState(waitForCdcEther);

// Need to subclass QEventTransition and implement virtuals 
// onTransition and eventTest?

detected->addTransition();
notDetected->addTransition();
waitForIfDown->addTransition();
waitForCdcEther->addTransition();

m_machine.setInitialState(notDetected);
m_machine.start();

このコードが存在する Detector オブジェクトで startTimer を呼び出すことができます。次に、Detector::timerEvent で、ユーザー定義の「タイムアウト」イベントをステート マシンにポストできます。また、トランジションごとに新しいタイマーを開始する必要があります。各トランジションのアクションは、QEventTransition のサブクラス、おそらく「onTransition」メソッドで発生します。これらの (一意の) 遷移オブジェクトのそれぞれに Detector オブジェクトを渡して、Detector が startTimer() を呼び出すようにするにはどうすればよいですか? また、2 つのトランジションにガード条件を実装する方法がわかりません。QAbstractTransition に仮想の「eventTest」が表示されますが、それを使用してガードを実装する方法がよくわかりません。私の考えはまだQtのやり方ではないと確信しています。

Qt に関する 2 冊の本 (Summerfield と Ezust から) と、http://doc.qt.io/qt-5/statemachine-api.html#events-transitions-and- も参照しました。警備員。本は QStateMachine についてまったく言及していません。Qt のオンライン ドキュメントには、汎用ステート マシンのサンプル コードが十分にないように思えます。既存の信号を使用してトランジションを作成する方法をうまく示していますが、ユーザー定義のイベントは示していません。

どんな助けでも大歓迎です。ありがとう。

シンプルな検出ステート マシン

編集: Detector::timerEvent() 関数の基本的な switch ステートメントを使用して、独自の単純なステート マシンを実装できることがわかりました。私は今これを行っていますが、QStateMachine を使用してこれを行う方法を理解すること に非常に興味があります。

4

0 に答える 0