熊 萱 杜 祝 譚欽文
(1.中國船舶重工集團公司第七二二研究所 武漢 430079)(2.中國石化化工銷售有限公司華中分公司 武漢 430079)
嵌入式系統的廣泛使用和日益增加的用戶需求,使得簡單的圖形用戶界面(Graphical User Interface,簡稱GUI)已無法滿足系統易用性的要求,而具有友好GUI的嵌入式系統將成為必然選擇[1~3]。QT Quick是 Qt4.7中推出的一項新技術,它引入了一種陳述性的腳本語言QML,用于動態設計和描述GUI,使設計過程快速靈活,易于使用。
在開發一個復雜的嵌入式軟件項目時,經常會遇到這樣一個問題:整個系統按照功能結構被劃分成多個模塊,如何保證各個模塊間的獨立性,即保證各個模塊間的松散耦合性和模塊自身的高內聚性,使整個系統架構功能層次結構分明,模塊間的通信簡潔明了。特別地,該問題在具有GUI功能的嵌入式軟件項目中顯得尤為突出。
針對上述問題,本文基于QT Quick技術,提出了一種消息分發模型,并對該模型實現的關鍵技術進行了研究,最后,結合工程實際應用,詳細闡述了消息分發模型的連接關系和分發流程。
結合工程實際應用構建消息分發模型如圖1所示。
整個消息分發模型分為三個層次:消息收發層、邏輯處理層及界面顯示層。消息收發層與邏輯處理層由C/C++語言實現,界面顯示層主要由QML語言實現。

圖1 消息分發模型
消息收發層為消息分發的主模塊,一方面完成與外界消息的接收與發送功能,另一方面根據消息的接收目標完成消息的下發功能;邏輯處理層由消息處理子模塊組成,主要完成消息的邏輯處理,并與界面進行交互控制的功能;界面顯示層涵蓋了所有界面模塊,完成界面的呈現及與用戶交互的功能。
該消息分發模型有以下的優點:
1)采用分層架構,結構層次分明,功能層次清晰,提高了架構的穩定性和維護性;
2)與外界采用消息方式進行交互,降低了與外界模塊的耦合度,開發人員可根據工程實際運用環境靈活實現消息交互方式,例如網絡報文方式、進程間通信方式等;
3)模型中的邏輯控制比重(占整個系統)也可根據實際需求靈活劃分,提高了整個分發模型的彈性力度。
任何嵌入式應用程序的開發,都會涉及UI與APP的通信機制選擇問題,下面就QT特有的通信機制及實際應用中的問題進行探討。
在QT開發環境中,對象間的通信是利用“信號和槽”(signal and slot)的機制來實現的,這種機制為消息分發模型的實現提供了基礎?!靶盘柡筒邸笔荙T自行定義的一種通信機制[4~6]:當指定的信號發射出去時,與該信號相連接的所有槽函數將會立刻執行。信號與槽的關聯[7]是通過調用QObject對象的connect函數來實現的,它是連接信號和槽的橋梁。
信號和槽的連接方式如圖2所示,當發射者(Object 1)發射信號(signal 1)時,接收者(Object 2)的槽函數(slot 1)想要被調用,只需使用connect(Object 1,signal 1,Object 2,slot 1),就可以實現。

圖2 信號與槽的連接示意圖
需要特別指出的是,可以將多個信號與單個槽進行連接,也可以將單個的信號與多個槽進行連接,甚至還可以將一個信號與另外一個信號相連接[8]。
在各軟件模塊間,經常是以消息形式進行通信[9]。借助QT的信號和槽機制進行消息傳遞,關鍵難點在于信號與槽間如何傳遞復雜的參數,即自定義消息結構體。下面以一個自定義消息結構體為例,具體闡述實現步驟:
1)自定義消息結構MsgStruct,可按照自己需求定義消息的結構,一般包括消息類型、處理對象及傳遞參數等相關信息;
2)使用Q_DECLARE_METATYPE對消息結構體進行宏定義:
Q_DECLARE_METATYPE(MsgStruct);
3)以QVariant的形式對該消息結構體進行封裝:

4)在構造函數中對QVariant進行注冊:
qRegisterMetaType<QVariant>("QVariant");
這樣,在信號和槽的機制中就可以使用QVariant作為參數類型進行數據傳遞了:
1)發射信號中帶有該消息結構的參數:

2)連接接收帶有該消息結構參數的槽函數:

3)在槽函數中處理消息:

對于一個C++對象而言,任何數據都可以通過QT的MetaObject System嵌入QML上下文中,同時,任何的QML對象數據也都可以通過Metaobject system在C++端進行直接訪問[12]。

圖3 QML與C++對象交互示意圖
QML與C++對象交互示意圖如圖3所示。在實際工程應用中,一般采用將C++對象“嵌入”(Expose)到QML上下文中的方式來進行交互,同時,還借助信號與槽的方式來實現消息的回傳。用戶的操作可通過QML Object調用C++Object的slots進行業務邏輯處理;經業務邏輯處理后,其結果可由C++Object采用發送信號的方式,發送給與其相連接的QML槽函數(Connections可視為槽)來進行處理,該槽函數中包含了QML Object的邏輯處理。這樣便實現了用戶操作到業務邏輯的處理,和業務邏輯處理到界面控制的流程。
消息分發對象信號與槽的連接關系圖如圖4所示。為簡化連接關系圖,圖中的“[A,B]”表示信號A與槽B相連接。Qbject_M表示模型中的主模塊對象;Object_A表示邏輯處理子模塊對象(邏輯處理層應包含有多個對象,為簡化邏輯關系圖,僅用一個Object_A來表示);QML_A對應Object_A的界面顯示對象。

圖4 消息分發對象連接關系圖
處于消息收發層主模塊Objecct_M對象的發消息信號與多個子模塊的收消息槽相連接,圖4(a)為主模塊消息下發的流程,當主模塊收到外來消息后觸發發消息信號,各子模塊便會收到主模塊的消息,然后各子模塊根據消息標識來處理屬于自己的消息;類似地,子模塊將消息處理后,通過觸發與界面顯示對象槽相連接的發信號,來告知相應界面顯示對象進行處理。
反之,如圖4(b)所示,當界面顯示模塊收到用戶操作輸入后,界面顯示模塊可通過直接訪問對應子模塊槽函數的方法(此時,子模塊對于已“嵌入”到QML對象上下文中),或觸發與子模塊對象槽相連接的發信號,來告知子模塊對象進行邏輯處理;子模塊處理后,根據實際情況,同樣采用信號與槽的機制來回傳用戶處理消息到主模塊;主模塊收到子模塊回傳的消息后,調用外發消息函數對消息進行外發。
QT Quick是一種高級用戶界面新技術,使用它可輕松地創建供移動和嵌入式設備使用的動態觸摸式界面和輕量級應用程序,具有廣闊的市場運用前景。本文結合工程運用實際,對具有GUI功能的嵌入式應用程序中模塊間消息分發問題進行了探討,并構建了一種基于QT Quick的消息分發模型來供開發人員參考,本模型簡單易用、調用靈活,具有較高的工程應用價值。
[1]魏永明.實時嵌入式Linux系統GUI的發展與展望[J].微電腦世界,2000(49):25-28.
[2]倪繼利.Qt及Linux操作系統窗口設計[M].北京:電子工業出版社,2006:5-23.
[3]陳爽.Linux與Qt程序設計[M].北京:清華大學出版社,2011:6-18.
[4]Jasmin Blanchette.C++ GUI Qt4編程[M].北京:電子工業出版社,2008:1-35.
[5]張娟,張雪蘭.基于嵌入式Linux的GUI應用程序的實現[J].計算機應用,2003,23(4):115-117.
[6]許建.基于QT的嵌入式瀏覽器和GUI的實現[D].西安:西安電子科技,2008:20-24.
[7]黃超.基于Qt的嵌入式GUI的研究與實現[D].吉林:吉林大學,2011:20-26.
[8]陳英革,馬力,王小英.Qt/E中信號和槽機制的分析及教學實踐[J].常熟理工學院學報,2008,22(10):108-112.
[9]宋智寧,姚維.基于Qte通信機制的GUI系統[J].機電工程,2007,24(3):77-80.
[10]李升亮,徐劍鋒,李峻林.嵌入式系統中的多窗口GUI系統的研究[J].計算機與數字工程,2008,36(10).
[11]陳鯤,陳云秋,劉信新.基于Qt/Embedded的嵌入式Linux應用程序的設計[J].計算機與數字工程,2009,37(1).
[12]范鵬.基于Qt的嵌入式Linux系統GUI的研究與實現[D].北京:北京郵電大學,2011:23-28.