SCXML和QScxml使用總結

2021-08-08 10:31:41 字數 4222 閱讀 2454

最近接觸了scxml這個狀態描述文字,簡單來講就是描述了整個狀態的變遷過程的一種xml格式的**。qt labs中有乙個專案就是qscxml,它基於qstatemachine上層製作,可以直接讀取scxml格式的檔案生成內部狀態物件和成員,可以直接在qt中進行狀態變遷,十分方便。

先來簡單介紹一下scxml的格式,以

<

scxml

initial

="firststate"

version

="0.9"

xmlns

="">

作為整個scxml的開頭,scxml標籤旁的initial表示狀態機啟動之後進入的第乙個初始化狀態,在這裡我寫了firststate,表示狀態幾一啟動,就進入了firststate.

<

state

id="firststate"

initial

="firstchildnode"

>

以state標籤開頭表示了狀態的基本概念,其中的id是作為該狀態的索引號給你之後寫target進行索引,這個時候同學會看到又出現了乙個initial,這時的firstchildnode表示此時的firststate並不是乙個原子狀態,而是乙個組合狀態的父狀態。而firstchildnode恰恰就是它的子狀態。也就是說進入了firststate之後,就會立即進入firstchildnode,期間如果你呼叫了和標籤,你會發現呼叫了多次,不必奇怪,其實你的狀態是進入了一層一層中的最裡層,每進一層就會呼叫和。

<

transition

event

="key.a"

target

="secondstate"

>

transition

>

<

transition

event

="key.b"

target

="thirdstate"

>

transition

>

又來新東西了,這個標籤表示真正的事務處理過程,之後的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

="fourhstate"

>

transition

>

<

transition

event

="key.b"

target

="fifthstate"

>

transition

>

這個時候狀態機會優先處理最子層的事務處理,如果狀態機發現在最子層並沒有完成該事件(包括沒有找到該translation和找到translation可是cond為false)都會將事件向上傳遞給父狀態進行處理。

在來說說比較有用的標籤,這個標籤可以放在中也可以放在中,當放在

<

transition

event

="key.a"

target

="fourhstate"

cond

="istrue"

>

transition

>

表明當istrue為true的時候,target才真正進行轉移(在這裡istrue即可以是簡單變數也可以是script函式來返回bool值),比較常用的用法有

<

translation

event

="key.a"

>

<

if cond

="istrue()"

>

<

script

>

funca()

script

>

<

elseif

cond

="isfalse()"

/>

<

script

>

funcb()

script

>

<

else

/>

<

script

>

funcc()

script

>

if>

translation

>

表明事件key.a來的時候進行cond判斷來呼叫相應的script。

另外我們也可以用到狀態機在上而下處理事件的機制,來進行靈活的target動態轉換工作.

<

transition

event

="key.a"

target

="a"

cond

="istrue()"

/>

<

transition

event

="key.a"

target

="b"

>

細心的你一定會發現,怎麼兩個translation的event一樣。其實這種用法在w3c的examples中也提到過,因為狀態機在上而下的處理機制,你可以在斷言為false的時候有乙個預設的target,而在true的時候進入你事先設定的target,可以非常靈活的使用這種機制進行判斷.

另外介紹一下兩個也比較重要的標籤,在上文也提到過和,

<

onentry

>

<

script

>

enterstate("a

");script

>

onentry

>

<

onexit

>

<

script

>

exitstate("b

");script

>

表明在進入和退出該狀態的時候自動觸發的事件,這裡預設呼叫的script,你可以很靈活的控制狀態切換時應該需要的工作.

qscxml中有乙個功能非常強大的函式

void qscxml::registerobject (qobject* o, const qstring & name, bool recursive)
用它進行註冊之後,你可以在scxml的檔案中寫各種script function,比如你註冊的時候m_scxml->registerobject(this, "widget", true),這個時候你就可以在scxml檔案中寫下

<

script

>

function

show()

script

>

表明無論你在translation還是onentry還是onexit中的標籤寫show()這個函式,你最終都會通過qscxml這個強大的類讓你可以和它進行互動。如果你嫌寫script function麻煩,

你也可以直接在標籤中寫上

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....