Qt的狀態機器運行在自己的事件迴圈中。對一個訊號裝換(QSignalTransition objects),當狀態機器接受一個訊號時,狀態機器自動會產生一個相應的訊號事件即QStateMachine::SignalEvent給他自己。對於QObject的事件過渡,則產生一個QStateMachine::WrappedEvent事件。
在前面的例子中
s.addTransition(&iButton,SIGNAL(clicked()),&is);我們之間連載了一個訊號上,這個訊號不帶參數,所以我們不需要分別處理,如果對一個狀態對外部要分別處理,那隻有添加按鈕,顯然不好。如果訊號帶了參數,那些在這基礎之上是不能起作用的,那麼就需要用到QSignalTransition。
下面舉了一個例子,使用一個QcheckBox來控制兩個狀態
首要因為有連個不同的狀態,所以要通過繼承QSignalTransition得到一個CheckedTransition和一個UncheckedTransition分別對應checked和unchecked。需要實現一個虛函數eventTest,因為訊號帶參數,所以在這種對參數進行比較得到我們需要的訊號。
bool UncheckedTransition::eventTest(QEvent *event){ if (!QSignalTransition::eventTest(event)) { return false; } else { QStateMachine::SignalEvent *e = static_cast<QStateMachine::SignalEvent*>(event); return (e->arguments().at(0).toInt() == Qt::Unchecked); }}
然後建立一個狀態機器就可以,添加這兩個基於signal的過渡就行了。
p_sm = new QStateMachine(this); p_s1 = new QState; p_s2 = new QState; p_s3 = new QState; p_sm->addState(p_s1); p_sm->addState(p_s2); p_sm->addState(p_s3); CheckedTransition *c = new CheckedTransition(ui->checkBox); c->setTargetState(p_s2); p_s1->addTransition(c); UncheckedTransition *u = new UncheckedTransition(ui->checkBox); u->setTargetState(p_s3); p_s1->addTransition(u); p_s2->addTransition(p_s1); p_s3->addTransition(p_s1); p_sm->setInitialState(p_s1); connect(ui->pushButton,SIGNAL(clicked()),p_sm,SLOT(start())); p_s2->assignProperty(ui->label,"text","checd"); p_s3->assignProperty(ui->label,"text","unchecd");