熊 萱 杜 祝 譚欽文
(1.中國(guó)船舶重工集團(tuán)公司第七二二研究所 武漢 430079)(2.中國(guó)石化化工銷(xiāo)售有限公司華中分公司 武漢 430079)
嵌入式系統(tǒng)的廣泛使用和日益增加的用戶(hù)需求,使得簡(jiǎn)單的圖形用戶(hù)界面(Graphical User Interface,簡(jiǎn)稱(chēng)GUI)已無(wú)法滿(mǎn)足系統(tǒng)易用性的要求,而具有友好GUI的嵌入式系統(tǒng)將成為必然選擇[1~3]。QT Quick是 Qt4.7中推出的一項(xiàng)新技術(shù),它引入了一種陳述性的腳本語(yǔ)言QML,用于動(dòng)態(tài)設(shè)計(jì)和描述GUI,使設(shè)計(jì)過(guò)程快速靈活,易于使用。
在開(kāi)發(fā)一個(gè)復(fù)雜的嵌入式軟件項(xiàng)目時(shí),經(jīng)常會(huì)遇到這樣一個(gè)問(wèn)題:整個(gè)系統(tǒng)按照功能結(jié)構(gòu)被劃分成多個(gè)模塊,如何保證各個(gè)模塊間的獨(dú)立性,即保證各個(gè)模塊間的松散耦合性和模塊自身的高內(nèi)聚性,使整個(gè)系統(tǒng)架構(gòu)功能層次結(jié)構(gòu)分明,模塊間的通信簡(jiǎn)潔明了。特別地,該問(wèn)題在具有GUI功能的嵌入式軟件項(xiàng)目中顯得尤為突出。
針對(duì)上述問(wèn)題,本文基于QT Quick技術(shù),提出了一種消息分發(fā)模型,并對(duì)該模型實(shí)現(xiàn)的關(guān)鍵技術(shù)進(jìn)行了研究,最后,結(jié)合工程實(shí)際應(yīng)用,詳細(xì)闡述了消息分發(fā)模型的連接關(guān)系和分發(fā)流程。
結(jié)合工程實(shí)際應(yīng)用構(gòu)建消息分發(fā)模型如圖1所示。
整個(gè)消息分發(fā)模型分為三個(gè)層次:消息收發(fā)層、邏輯處理層及界面顯示層。消息收發(fā)層與邏輯處理層由C/C++語(yǔ)言實(shí)現(xiàn),界面顯示層主要由QML語(yǔ)言實(shí)現(xiàn)。
圖1 消息分發(fā)模型
消息收發(fā)層為消息分發(fā)的主模塊,一方面完成與外界消息的接收與發(fā)送功能,另一方面根據(jù)消息的接收目標(biāo)完成消息的下發(fā)功能;邏輯處理層由消息處理子模塊組成,主要完成消息的邏輯處理,并與界面進(jìn)行交互控制的功能;界面顯示層涵蓋了所有界面模塊,完成界面的呈現(xiàn)及與用戶(hù)交互的功能。
該消息分發(fā)模型有以下的優(yōu)點(diǎn):
1)采用分層架構(gòu),結(jié)構(gòu)層次分明,功能層次清晰,提高了架構(gòu)的穩(wěn)定性和維護(hù)性;
2)與外界采用消息方式進(jìn)行交互,降低了與外界模塊的耦合度,開(kāi)發(fā)人員可根據(jù)工程實(shí)際運(yùn)用環(huán)境靈活實(shí)現(xiàn)消息交互方式,例如網(wǎng)絡(luò)報(bào)文方式、進(jìn)程間通信方式等;
3)模型中的邏輯控制比重(占整個(gè)系統(tǒng))也可根據(jù)實(shí)際需求靈活劃分,提高了整個(gè)分發(fā)模型的彈性力度。
任何嵌入式應(yīng)用程序的開(kāi)發(fā),都會(huì)涉及UI與APP的通信機(jī)制選擇問(wèn)題,下面就QT特有的通信機(jī)制及實(shí)際應(yīng)用中的問(wèn)題進(jìn)行探討。
在QT開(kāi)發(fā)環(huán)境中,對(duì)象間的通信是利用“信號(hào)和槽”(signal and slot)的機(jī)制來(lái)實(shí)現(xiàn)的,這種機(jī)制為消息分發(fā)模型的實(shí)現(xiàn)提供了基礎(chǔ)?!靶盘?hào)和槽”是QT自行定義的一種通信機(jī)制[4~6]:當(dāng)指定的信號(hào)發(fā)射出去時(shí),與該信號(hào)相連接的所有槽函數(shù)將會(huì)立刻執(zhí)行。信號(hào)與槽的關(guān)聯(lián)[7]是通過(guò)調(diào)用QObject對(duì)象的connect函數(shù)來(lái)實(shí)現(xiàn)的,它是連接信號(hào)和槽的橋梁。
信號(hào)和槽的連接方式如圖2所示,當(dāng)發(fā)射者(Object 1)發(fā)射信號(hào)(signal 1)時(shí),接收者(Object 2)的槽函數(shù)(slot 1)想要被調(diào)用,只需使用connect(Object 1,signal 1,Object 2,slot 1),就可以實(shí)現(xiàn)。
圖2 信號(hào)與槽的連接示意圖
需要特別指出的是,可以將多個(gè)信號(hào)與單個(gè)槽進(jìn)行連接,也可以將單個(gè)的信號(hào)與多個(gè)槽進(jìn)行連接,甚至還可以將一個(gè)信號(hào)與另外一個(gè)信號(hào)相連接[8]。
在各軟件模塊間,經(jīng)常是以消息形式進(jìn)行通信[9]。借助QT的信號(hào)和槽機(jī)制進(jìn)行消息傳遞,關(guān)鍵難點(diǎn)在于信號(hào)與槽間如何傳遞復(fù)雜的參數(shù),即自定義消息結(jié)構(gòu)體。下面以一個(gè)自定義消息結(jié)構(gòu)體為例,具體闡述實(shí)現(xiàn)步驟:
1)自定義消息結(jié)構(gòu)MsgStruct,可按照自己需求定義消息的結(jié)構(gòu),一般包括消息類(lèi)型、處理對(duì)象及傳遞參數(shù)等相關(guān)信息;
2)使用Q_DECLARE_M(jìn)ETATYPE對(duì)消息結(jié)構(gòu)體進(jìn)行宏定義:
Q_DECLARE_M(jìn)ETATYPE(MsgStruct);
3)以QVariant的形式對(duì)該消息結(jié)構(gòu)體進(jìn)行封裝:
4)在構(gòu)造函數(shù)中對(duì)QVariant進(jìn)行注冊(cè):
qRegisterMetaType<QVariant>("QVariant");
這樣,在信號(hào)和槽的機(jī)制中就可以使用QVariant作為參數(shù)類(lèi)型進(jìn)行數(shù)據(jù)傳遞了:
1)發(fā)射信號(hào)中帶有該消息結(jié)構(gòu)的參數(shù):
2)連接接收帶有該消息結(jié)構(gòu)參數(shù)的槽函數(shù):
3)在槽函數(shù)中處理消息:
對(duì)于一個(gè)C++對(duì)象而言,任何數(shù)據(jù)都可以通過(guò)QT的MetaObject System嵌入QML上下文中,同時(shí),任何的QML對(duì)象數(shù)據(jù)也都可以通過(guò)Metaobject system在C++端進(jìn)行直接訪(fǎng)問(wèn)[12]。
圖3 QML與C++對(duì)象交互示意圖
QML與C++對(duì)象交互示意圖如圖3所示。在實(shí)際工程應(yīng)用中,一般采用將C++對(duì)象“嵌入”(Expose)到QML上下文中的方式來(lái)進(jìn)行交互,同時(shí),還借助信號(hào)與槽的方式來(lái)實(shí)現(xiàn)消息的回傳。用戶(hù)的操作可通過(guò)QML Object調(diào)用C++Object的slots進(jìn)行業(yè)務(wù)邏輯處理;經(jīng)業(yè)務(wù)邏輯處理后,其結(jié)果可由C++Object采用發(fā)送信號(hào)的方式,發(fā)送給與其相連接的QML槽函數(shù)(Connections可視為槽)來(lái)進(jìn)行處理,該槽函數(shù)中包含了QML Object的邏輯處理。這樣便實(shí)現(xiàn)了用戶(hù)操作到業(yè)務(wù)邏輯的處理,和業(yè)務(wù)邏輯處理到界面控制的流程。
消息分發(fā)對(duì)象信號(hào)與槽的連接關(guān)系圖如圖4所示。為簡(jiǎn)化連接關(guān)系圖,圖中的“[A,B]”表示信號(hào)A與槽B相連接。Qbject_M(jìn)表示模型中的主模塊對(duì)象;Object_A表示邏輯處理子模塊對(duì)象(邏輯處理層應(yīng)包含有多個(gè)對(duì)象,為簡(jiǎn)化邏輯關(guān)系圖,僅用一個(gè)Object_A來(lái)表示);QML_A對(duì)應(yīng)Object_A的界面顯示對(duì)象。
圖4 消息分發(fā)對(duì)象連接關(guān)系圖
處于消息收發(fā)層主模塊Objecct_M(jìn)對(duì)象的發(fā)消息信號(hào)與多個(gè)子模塊的收消息槽相連接,圖4(a)為主模塊消息下發(fā)的流程,當(dāng)主模塊收到外來(lái)消息后觸發(fā)發(fā)消息信號(hào),各子模塊便會(huì)收到主模塊的消息,然后各子模塊根據(jù)消息標(biāo)識(shí)來(lái)處理屬于自己的消息;類(lèi)似地,子模塊將消息處理后,通過(guò)觸發(fā)與界面顯示對(duì)象槽相連接的發(fā)信號(hào),來(lái)告知相應(yīng)界面顯示對(duì)象進(jìn)行處理。
反之,如圖4(b)所示,當(dāng)界面顯示模塊收到用戶(hù)操作輸入后,界面顯示模塊可通過(guò)直接訪(fǎng)問(wèn)對(duì)應(yīng)子模塊槽函數(shù)的方法(此時(shí),子模塊對(duì)于已“嵌入”到QML對(duì)象上下文中),或觸發(fā)與子模塊對(duì)象槽相連接的發(fā)信號(hào),來(lái)告知子模塊對(duì)象進(jìn)行邏輯處理;子模塊處理后,根據(jù)實(shí)際情況,同樣采用信號(hào)與槽的機(jī)制來(lái)回傳用戶(hù)處理消息到主模塊;主模塊收到子模塊回傳的消息后,調(diào)用外發(fā)消息函數(shù)對(duì)消息進(jìn)行外發(fā)。
QT Quick是一種高級(jí)用戶(hù)界面新技術(shù),使用它可輕松地創(chuàng)建供移動(dòng)和嵌入式設(shè)備使用的動(dòng)態(tài)觸摸式界面和輕量級(jí)應(yīng)用程序,具有廣闊的市場(chǎng)運(yùn)用前景。本文結(jié)合工程運(yùn)用實(shí)際,對(duì)具有GUI功能的嵌入式應(yīng)用程序中模塊間消息分發(fā)問(wèn)題進(jìn)行了探討,并構(gòu)建了一種基于QT Quick的消息分發(fā)模型來(lái)供開(kāi)發(fā)人員參考,本模型簡(jiǎn)單易用、調(diào)用靈活,具有較高的工程應(yīng)用價(jià)值。
[1]魏永明.實(shí)時(shí)嵌入式Linux系統(tǒng)GUI的發(fā)展與展望[J].微電腦世界,2000(49):25-28.
[2]倪繼利.Qt及Linux操作系統(tǒng)窗口設(shè)計(jì)[M].北京:電子工業(yè)出版社,2006:5-23.
[3]陳爽.Linux與Qt程序設(shè)計(jì)[M].北京:清華大學(xué)出版社,2011:6-18.
[4]Jasmin Blanchette.C++ GUI Qt4編程[M].北京:電子工業(yè)出版社,2008:1-35.
[5]張娟,張雪蘭.基于嵌入式Linux的GUI應(yīng)用程序的實(shí)現(xiàn)[J].計(jì)算機(jī)應(yīng)用,2003,23(4):115-117.
[6]許建.基于QT的嵌入式瀏覽器和GUI的實(shí)現(xiàn)[D].西安:西安電子科技,2008:20-24.
[7]黃超.基于Qt的嵌入式GUI的研究與實(shí)現(xiàn)[D].吉林:吉林大學(xué),2011:20-26.
[8]陳英革,馬力,王小英.Qt/E中信號(hào)和槽機(jī)制的分析及教學(xué)實(shí)踐[J].常熟理工學(xué)院學(xué)報(bào),2008,22(10):108-112.
[9]宋智寧,姚維.基于Qte通信機(jī)制的GUI系統(tǒng)[J].機(jī)電工程,2007,24(3):77-80.
[10]李升亮,徐劍鋒,李峻林.嵌入式系統(tǒng)中的多窗口GUI系統(tǒng)的研究[J].計(jì)算機(jī)與數(shù)字工程,2008,36(10).
[11]陳鯤,陳云秋,劉信新.基于Qt/Embedded的嵌入式Linux應(yīng)用程序的設(shè)計(jì)[J].計(jì)算機(jī)與數(shù)字工程,2009,37(1).
[12]范鵬.基于Qt的嵌入式Linux系統(tǒng)GUI的研究與實(shí)現(xiàn)[D].北京:北京郵電大學(xué),2011:23-28.