最近接觸了scxml這個狀態描述文字,簡單來講就是描述了整個狀態的變遷過程的一種xml格式的**。qt labs中有乙個專案就是qscxml,它基於qstatemachine上層製作,可以直接讀取scxml格式的檔案生成內部狀態物件和成員,可以直接在qt中進行狀態變遷,十分方便。
先來簡單介紹一下scxml的格式,以
<作為整個scxml的開頭,scxml標籤旁的initial表示狀態機啟動之後進入的第乙個初始化狀態,在這裡我寫了firststate,表示狀態幾一啟動,就進入了firststate.scxml
initial
="firststate"
version
="0.9"
xmlns
="">
<以state標籤開頭表示了狀態的基本概念,其中的id是作為該狀態的索引號給你之後寫target進行索引,這個時候同學會看到又出現了乙個initial,這時的firstchildnode表示此時的firststate並不是乙個原子狀態,而是乙個組合狀態的父狀態。而firstchildnode恰恰就是它的子狀態。也就是說進入了firststate之後,就會立即進入firstchildnode,期間如果你呼叫了和標籤,你會發現呼叫了多次,不必奇怪,其實你的狀態是進入了一層一層中的最裡層,每進一層就會呼叫和。state
id="firststate"
initial
="firstchildnode"
>
<又來新東西了,這個標籤表示真正的事務處理過程,之後的event屬性表示你傳遞給qscxml中的postnamedevent(const qstring)函式中的qstring,所以我之前提過那個id的作用,就是全域性的索引號,同時請注意:scxml中預設的event是字首查詢,也就是說對於event="gametest"來說,你輸入"gametest","game","game.","game.*"效果是完全一樣的,不過我試了下在qscxml中只有第一種和第三種有效(官方說明)。之後的自然很好理解,就是你在這個狀態下,經過了event事件,達到了target狀態(target不能接收函式,必須是字串狀態變數而cond可以接收函式或者字串)。例子中就表示無論你在firststate中的哪個孩子中,只要你收到了key.a事件,你都會跳出子狀態乃至父狀態,直接跳到對應的secondstate中去。注意:寫在父狀態中的translation是給它以及它的孩子全域性共享的,如果你覺得你可能在孩子節點中對於某乙個事件你不滿意,你想要重寫,那你完全可以在firstchildnode中寫下transition
event
="key.a"
target
="secondstate"
>
transition
>
<
transition
event
="key.b"
target
="thirdstate"
>
transition
>
<這個時候狀態機會優先處理最子層的事務處理,如果狀態機發現在最子層並沒有完成該事件(包括沒有找到該translation和找到translation可是cond為false)都會將事件向上傳遞給父狀態進行處理。transition
event
="key.a"
target
="fourhstate"
>
transition
>
<
transition
event
="key.b"
target
="fifthstate"
>
transition
>
在來說說比較有用的標籤,這個標籤可以放在中也可以放在中,當放在
<表明當istrue為true的時候,target才真正進行轉移(在這裡istrue即可以是簡單變數也可以是script函式來返回bool值),比較常用的用法有transition
event
="key.a"
target
="fourhstate"
cond
="istrue"
>
transition
>
<表明事件key.a來的時候進行cond判斷來呼叫相應的script。translation
event
="key.a"
>
<
if cond
="istrue()"
>
<
script
>
funca()
script
>
<
elseif
cond
="isfalse()"
/>
<
script
>
funcb()
script
>
<
else
/>
<
script
>
funcc()
script
>
if>
translation
>
另外我們也可以用到狀態機在上而下處理事件的機制,來進行靈活的target動態轉換工作.
<細心的你一定會發現,怎麼兩個translation的event一樣。其實這種用法在w3c的examples中也提到過,因為狀態機在上而下的處理機制,你可以在斷言為false的時候有乙個預設的target,而在true的時候進入你事先設定的target,可以非常靈活的使用這種機制進行判斷.transition
event
="key.a"
target
="a"
cond
="istrue()"
/>
<
transition
event
="key.a"
target
="b"
>
另外介紹一下兩個也比較重要的標籤,在上文也提到過和,
<表明在進入和退出該狀態的時候自動觸發的事件,這裡預設呼叫的script,你可以很靈活的控制狀態切換時應該需要的工作.onentry
>
<
script
>
enterstate("a
");script
>
onentry
>
<
onexit
>
<
script
>
exitstate("b
");script
>
qscxml中有乙個功能非常強大的函式
void qscxml::registerobject (qobject* o, const qstring & name, bool recursive)用它進行註冊之後,你可以在scxml的檔案中寫各種script function,比如你註冊的時候m_scxml->registerobject(this, "widget", true),這個時候你就可以在scxml檔案中寫下
<表明無論你在translation還是onentry還是onexit中的標籤寫show()這個函式,你最終都會通過qscxml這個強大的類讓你可以和它進行互動。如果你嫌寫script function麻煩,script
>
function
show()
script
>
你也可以直接在標籤中寫上
widget.show();一樣可以直接執行。script function的強大不僅僅在於可以通過qscxml讓你和你的物件進行互動,同時它也可以用來做斷言cond判斷,比如
function istrue()你可以非常靈活的實現你自己類的斷言函式,配合之前的translation中的cond做到動態切換target,非常方便。
VMWare Workstation使用總結幾則
1 安裝 使用ghost盤安裝時一定要注意,需要把空盤建立分割槽並設定為主分割槽 pq的使用形式,進入pq找到磁碟設定為啟用 否則 啟動後顯示boot from network intel e1000 有時裝機忘了,只能從頭再來 安裝64位的虛擬機器時,需要把bios中virtual technol...
VMWare Workstation使用總結幾則
1 安裝 使用ghost盤安裝時一定要注意,需要把空盤建立分割槽並設定為主分割槽 pq的使用形式,進入pq找到磁碟設定為啟用 否則 啟動後顯示boot from network intel e1000 有時裝機忘了,只能從頭再來 安裝64位的虛擬機器時,需要把bios中virtual technol...
pytest parametrize 使用總結
pytest中裝飾器 pytest.mark.parametrize 引數名 list 可以實現測試用例引數化,類似ddt。如 pytest.mark.parametrize 請求方式,介面位址,傳參,預期結果 get www.baidu.com post www.baidu.com pytest....