版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
10.1Linux圖形開(kāi)發(fā)基礎(chǔ)10.2嵌入式Linux圖形用戶(hù)界面簡(jiǎn)介10.3Qt/Embedded嵌入式圖形開(kāi)發(fā)基礎(chǔ)練習(xí)題第10章嵌入式Linux圖形用戶(hù)界面編程
10.1Linux圖形開(kāi)發(fā)基礎(chǔ)
本節(jié)簡(jiǎn)單介紹圖形用戶(hù)界面GUI的一般架構(gòu),主要討論嵌入式Linux圖形開(kāi)發(fā)的基礎(chǔ)知識(shí),包括GUI的底層支持庫(kù)和高級(jí)函數(shù)庫(kù),為后面的進(jìn)一步敘述奠定基礎(chǔ)。10.1.1GUI的一般架構(gòu)
GUI是GraphicalUserInterface的簡(jiǎn)稱(chēng),即圖形用戶(hù)界面。圖形用戶(hù)界面(GUI)是計(jì)算機(jī)系統(tǒng)中最為成熟的人機(jī)交換技術(shù),是計(jì)算機(jī)與用戶(hù)之間的對(duì)話(huà)接口。它是一個(gè)圖形組成的用戶(hù)界面。比如,Windows界面、OS2界面等都是GUI。
GUI系統(tǒng)在邏輯上一般可分為以下幾層:
(1)最底層I/O設(shè)備驅(qū)動(dòng):直接與輸入硬件打交道,完成I/O設(shè)備的驅(qū)動(dòng),包括顯示設(shè)備驅(qū)動(dòng)、鼠標(biāo)驅(qū)動(dòng)、鍵盤(pán)驅(qū)動(dòng)等,構(gòu)成了GUI的硬件基礎(chǔ)。
(2)中間層圖形引擎:直接和最底層I/O設(shè)備驅(qū)動(dòng)打交道,主要完成一些圖形操作和圖形管理,如畫(huà)點(diǎn)、畫(huà)線(xiàn)、區(qū)域填充、畫(huà)窗口及按鈕等。
(3)最上層GUI應(yīng)用程序接口(API):是提供給程序員的編程接口,以快速開(kāi)發(fā)GUI應(yīng)用程序。
GUI是嵌入式系統(tǒng)中的一個(gè)重要問(wèn)題,越來(lái)越多的嵌入式系統(tǒng)要求提供全功能的Web瀏覽器,而這就要求有一個(gè)高性能、高可靠的GUI支持。由于嵌入式系統(tǒng)本身的特殊性,嵌入式GUI要求簡(jiǎn)單、直觀、可靠、占用資源小且反應(yīng)快速,以適應(yīng)系統(tǒng)硬件資源有限的條件。另外,GUI還應(yīng)具備高度可移植性與可裁減性,以適應(yīng)不同的硬件條件和使用需求。總體來(lái)講,嵌入式GUI應(yīng)具備以下特點(diǎn):
(1)體積?。?/p>
(2)耗用系統(tǒng)資源?。?/p>
(3)上層接口與硬件無(wú)關(guān),高度可移植;
(4)高可靠性;
(5)在某些應(yīng)用場(chǎng)合應(yīng)具備實(shí)時(shí)性。10.1.2嵌入式GUI底層支持庫(kù)
一個(gè)能夠移植到多種硬件平臺(tái)上的嵌入式GUI系統(tǒng),應(yīng)至少抽象出兩類(lèi)設(shè)備:
(1)圖形抽象層(GraphicAbstractLayer,GAL):基于圖形顯示設(shè)備,完成系統(tǒng)對(duì)具體顯示硬件設(shè)備的操作,為程序開(kāi)發(fā)人員提供統(tǒng)一的圖形設(shè)備編程接口。
(2)輸入抽象層(InputAbstractLayer,IAL):基于輸入設(shè)備,實(shí)現(xiàn)對(duì)不同輸入設(shè)備的控制操作,提供統(tǒng)一的調(diào)用窗口。
嵌入式GUI底層實(shí)現(xiàn)基礎(chǔ)如圖10-1所示。
目前應(yīng)用于嵌入式Linux系統(tǒng)中比較成熟、功能比較強(qiáng)大的GUI系統(tǒng)底層支持庫(kù)有XWindow、FrameBuffer、SVGALib、LibGGI等。圖10-1嵌入式GUI底層實(shí)現(xiàn)基礎(chǔ)
1.?XWindow
XWindow是Unix的圖形界面標(biāo)準(zhǔn),它是以斯坦福的圖形化操作系統(tǒng)WWindowsSystem為基礎(chǔ)而發(fā)展起來(lái)的一套網(wǎng)絡(luò)透明窗口系統(tǒng)。XWindow系統(tǒng)是目前Linux系統(tǒng)中處于主導(dǎo)地位的桌面圖形系統(tǒng)。所有Linux版本的圖形界面標(biāo)準(zhǔn)均遵循XWindow,簡(jiǎn)稱(chēng)X。
XWindow采用標(biāo)準(zhǔn)的客戶(hù)端/服務(wù)器(Client/Server)模式,即參與運(yùn)行的主體為客戶(hù)端(XClient)和服務(wù)端(XServer)。它由XServer、XClient、X協(xié)議、Xlib函數(shù)庫(kù)等組成。
(1)?XServer:主要是控制I/O設(shè)備的程序,對(duì)顯示器的輸出、鍵盤(pán)和鼠標(biāo)的輸入進(jìn)行管理,接收輸入設(shè)備的信息,并將其傳給XClient,而將XClient傳來(lái)的信息輸出到屏幕上,提供顯示功能。
(2)?XClient:也稱(chēng)客戶(hù)程序,是應(yīng)用程序的核心部分,與硬件無(wú)關(guān)。它位于后端,提供處理功能。
(3)?X協(xié)議:是XWindow系統(tǒng)中各單元間通信的標(biāo)準(zhǔn),主要負(fù)責(zé)XClient與XServer間的通信。
(4)?Xlib函數(shù)庫(kù):XWindow客戶(hù)程序的功能是通過(guò)調(diào)用Xlib中的函數(shù)實(shí)現(xiàn)的。
XWindow的這種工作方式為用戶(hù)提供了兩個(gè)重要的特性:一個(gè)是平臺(tái)無(wú)關(guān)性,即應(yīng)用程序可以在任何其他平臺(tái)的服務(wù)器上顯示其界面;另一個(gè)是網(wǎng)絡(luò)透明性,是指服務(wù)器和客戶(hù)端之間通信協(xié)議的運(yùn)作對(duì)計(jì)算機(jī)網(wǎng)絡(luò)是透明的,客戶(hù)端和服務(wù)器可以在同一臺(tái)計(jì)算機(jī)上,也可以不是,一個(gè)應(yīng)用程序不管是在本地運(yùn)行,還是在遠(yuǎn)程某臺(tái)機(jī)器上運(yùn)行,都可以實(shí)現(xiàn)在本地顯示。
2.?FrameBuffer
FrameBuffer是一種獨(dú)立于硬件的抽象圖形設(shè)備,是Linux抽象出來(lái)的供用戶(hù)態(tài)進(jìn)程實(shí)現(xiàn)直接寫(xiě)屏的設(shè)備。它模仿顯卡的功能,將顯卡硬件結(jié)構(gòu)抽象化。用戶(hù)可以將FrameBuffer看成是顯示內(nèi)存的一個(gè)映像,將其映射到進(jìn)程地址空間之后,就可以直接進(jìn)行讀/寫(xiě)操作,而寫(xiě)操作可以立即反映在屏幕上。
FrameBuffer設(shè)備提供了若干ioctl命令,通過(guò)這些命令,可以獲得顯示設(shè)備的一些固定信息(如顯存大小)、與顯示模式相關(guān)的可變信息(如分辨率、像素結(jié)構(gòu)等)以及偽彩色模式下的調(diào)色板信息等。此外,通過(guò)FrameBuffer設(shè)備還可以獲得當(dāng)前內(nèi)核所支持的加速顯示卡的類(lèi)型,這種類(lèi)型通常是和特定顯示芯片相關(guān)的。在獲得了加速芯片類(lèi)型之后,應(yīng)用程序就可以將PCI設(shè)備的內(nèi)存I/O(memio)映射到進(jìn)程的地址空間。這些memio一般是用來(lái)控制顯示卡的寄存器的,通過(guò)對(duì)這些寄存器的操作,應(yīng)用程序就可以控制特定顯卡的加速功能。
FrameBuffer本身不具備運(yùn)算數(shù)據(jù)的能力,它只暫存經(jīng)CPU運(yùn)算后的數(shù)據(jù)結(jié)果,并將結(jié)果送到顯示器中,中間不對(duì)數(shù)據(jù)做任何處理。它只是一個(gè)(提供顯示內(nèi)存和顯示芯片寄存器從物理內(nèi)存映射到進(jìn)程地址空間的)設(shè)備。所以,對(duì)于應(yīng)用程序而言,如果希望在FrameBuffer之上進(jìn)行圖形編程,還需要自己動(dòng)手完成其他許多工作。FrameBuffer就像一張畫(huà)布,使用什么樣的畫(huà)筆,如何畫(huà)畫(huà),還需要自己動(dòng)手完成。
FrameBuffer具有高度的可移植性、易使用性和穩(wěn)定性。使用Linux內(nèi)核的FrameBuffer驅(qū)動(dòng),可以輕松支持1024?×?768?×?32b/p以上的分辨率。目前,在可得到的絕大多數(shù)Linux版本所發(fā)行的內(nèi)核中,已經(jīng)預(yù)編譯了FrameBuffer支持。
3.?SVGALib
SVGALib(SuperVideoGraphicsArrayLib)是一個(gè)比較老的圖形支持庫(kù),是Linux系統(tǒng)中最早出現(xiàn)的非X圖形支持庫(kù)。這個(gè)庫(kù)從最初對(duì)標(biāo)準(zhǔn)VGA(VideoGraphicsArray)兼容芯片的支持開(kāi)始,一直發(fā)展到對(duì)老式SVGA芯片的支持以及對(duì)現(xiàn)今流行的高級(jí)視頻芯片的支持。它為用戶(hù)提供在控制臺(tái)上進(jìn)行圖形編程的接口,使用戶(hù)可以在PC兼容系統(tǒng)上方便地獲得圖形支持。但該系統(tǒng)存在以下不足:
(1)接口雜亂。SVGALib從最初的VGAlib發(fā)展而來(lái),保留了老系統(tǒng)的許多接口,而這些接口卻不能良好地迎合新顯示芯片的圖形能力。
(2)未能較好地隱藏硬件細(xì)節(jié)。許多操作不能自動(dòng)使用顯示芯片的加速能力支持。
(3)可移植性差。SVGALib目前只能運(yùn)行在X86平臺(tái)上,除Alpha平臺(tái)之外,對(duì)其他平臺(tái)的支持能力較差。
(4)?SVGALib作為一個(gè)老的圖形支持庫(kù),對(duì)高級(jí)圖形功能的支持(比如直線(xiàn)和曲線(xiàn)等)不能令人滿(mǎn)意,因此其應(yīng)用范圍越來(lái)越小,尤其在Linux內(nèi)核增加了FrameBuffer驅(qū)動(dòng)支持之后,有逐漸被其他圖形庫(kù)替代的跡象。
盡管SVGALib有許多缺點(diǎn),支持的顯卡種類(lèi)也不多,但是有許多的游戲及程序還是用它來(lái)做開(kāi)發(fā)的。此外,它是Linux
Console下的VGA驅(qū)動(dòng)函數(shù)庫(kù),如果用戶(hù)準(zhǔn)備在Console下撰寫(xiě)圖形功能的程序,目前來(lái)說(shuō)SVGALib是唯一的選擇。
4.?LibGGI
LibGGI(LibGraphicsInterface)是一個(gè)跨平臺(tái)的繪圖庫(kù)。它試圖建立一個(gè)一般性的圖形接口,而這個(gè)抽象接口連同相關(guān)的輸入抽象接口一起,可以方便地運(yùn)行在XWindow、SVGALib、FrameBuffer等之上。建立在LibGGI之上的應(yīng)用程序,不需重新編譯,就可以在上述這些底層圖形接口上運(yùn)行。
在Linux上,LibGGI是通過(guò)調(diào)用FrameBuffer或SVGALib來(lái)完成圖形操作的,可能速度比較慢。但在某些不支持FrameBuffer或是VGA的系統(tǒng)上使用LibGGI仍然是一種不錯(cuò)的選擇。目前,LibGGI的發(fā)展緩慢。10.1.3嵌入式GUI高級(jí)函數(shù)庫(kù)
1.?Xlib及其他相關(guān)函數(shù)庫(kù)
Xlib即我們上面所提到的XWindow系統(tǒng)中實(shí)現(xiàn)客戶(hù)程序功能所需調(diào)用的函數(shù)庫(kù)。在XWindow系統(tǒng)中進(jìn)行圖形編程時(shí),可以選擇直接使用Xlib。它實(shí)際上是對(duì)底層X(jué)協(xié)議的封裝,可通過(guò)該函數(shù)庫(kù)進(jìn)行一般的圖形輸出。如果用戶(hù)的XServer支持DGA(DirectGraphicsAccess,直接圖形訪(fǎng)問(wèn)),則可以通過(guò)DGA擴(kuò)展直接訪(fǎng)問(wèn)顯示設(shè)備,從而獲得加速支持。由于Xlib的接口原始而且復(fù)雜,使得應(yīng)用程序界面開(kāi)發(fā)效率低,因此一般用戶(hù)選擇其他高級(jí)一些的圖形庫(kù)作為基礎(chǔ),比如GTK(TheGIMPToolkit)、QT等。但GTK、QT等函數(shù)庫(kù)也存在龐大、占用系統(tǒng)資源多的缺點(diǎn),不太適合在嵌入式系統(tǒng)中使用。這時(shí)可選擇使用簡(jiǎn)單而靈活的GUI工具箱—FLTK(FastLightToolkit),它是一個(gè)輕量級(jí)的圖形函數(shù)庫(kù),特別適用占用資源少的環(huán)境。FLTK的主要功能集中在用戶(hù)界面上,提供了豐富的控件集。
2.?SDL
SDL(SimpleDirectMediaLayer)是一個(gè)跨平臺(tái)的多媒體游戲支持庫(kù),它是專(zhuān)門(mén)為游戲和多媒體應(yīng)用而設(shè)計(jì)開(kāi)發(fā)的。它可以運(yùn)行在許多平臺(tái)上,包括XWindow、XWindowwithDGA、LinuxFrameBuffer控制臺(tái)、LinuxSVGALib以及WindowsDirectX等。
SDL提供了對(duì)圖形、聲音、游戲桿、線(xiàn)程等的支持,還提供了對(duì)高級(jí)圖形的支持,比如Alpha混合、透明處理、YUV覆蓋、Gamma校正等。
此外,在SDL環(huán)境中能夠非常方便地加載支持OpenGL
(OpenGraphicsLib)的Mesa庫(kù),從而提供對(duì)二維和三維圖形的支持。可以說(shuō),SDL是編寫(xiě)跨平臺(tái)游戲和多媒體應(yīng)用的最佳平臺(tái),它得到了廣泛的應(yīng)用。
3.?Allegro
Allegro庫(kù)(Allegrolibrary)是一個(gè)自由的視頻游戲圖形庫(kù),是專(zhuān)門(mén)為X86平臺(tái)設(shè)計(jì)的。
Allegro可運(yùn)行在LinuxFrameBuffer控制臺(tái)、LinuxSVGALib、XWindow等系統(tǒng)上。它提供了一些豐富的圖形功能,包括矩形填充和樣條曲線(xiàn)生成等,而且具有較好的三維圖形顯示能力。由于Allegro的許多關(guān)鍵代碼是采用匯編語(yǔ)言編寫(xiě)的,因此該函數(shù)庫(kù)具有運(yùn)行速度快、資源占用少的優(yōu)點(diǎn)。但Allegro也存在如下缺點(diǎn):
(1)對(duì)線(xiàn)程的支持較差。Allegro的許多函數(shù)是非線(xiàn)程安全的,不能同時(shí)在兩個(gè)以上的線(xiàn)程中使用。
(2)對(duì)硬件加速能力的支持不足,在設(shè)計(jì)上沒(méi)有為硬件加速提供接口。
4.?Mesa3D
Mesa3D是一個(gè)支持3D的圖形函數(shù)庫(kù),它有API接口,非常像OpenGL(OpenGraphicsLib,即開(kāi)放式圖形庫(kù),是專(zhuān)業(yè)的3D程序接口,也是一個(gè)功能強(qiáng)大、調(diào)用方便的底層3D圖形庫(kù))。Mesa3D是Linux下OpenGL的取代產(chǎn)品,提供和OpenGL幾乎完全一致的接口。
Mesa3D還是一個(gè)遵循GPL協(xié)議(部分遵循LGPL協(xié)議)的自由軟件。因此,Mesa3D是一個(gè)兼容OpenGL規(guī)范的開(kāi)放源碼函數(shù)庫(kù),是目前Linux上提供專(zhuān)業(yè)三維圖形支持的唯一選擇。
此外,Mesa3D是一個(gè)跨平臺(tái)的函數(shù)庫(kù),能夠運(yùn)行在XWindow、XWindowwithDGA、BeOS、LinuxSVGALib等多種平臺(tái)上。
5.?DirectFB
DirectFB是一個(gè)基于FrameBuffer的圖形庫(kù),支持部分加速。DirectFB試圖建立一個(gè)兼容GTK(TheGIMPToolkit)的嵌入式GUI系統(tǒng)。它以可裝載函數(shù)庫(kù)的形勢(shì)提供對(duì)加速FrameBuffer驅(qū)動(dòng)程序的支持。目前,該函數(shù)庫(kù)正在開(kāi)發(fā)之中。
10.2嵌入式Linux圖形用戶(hù)界面簡(jiǎn)介
目前,嵌入式Linux的主流GUI系統(tǒng)主要有Qt/Embedded、MicroWindows、MiniGUI和OpenGUI,這些GUI在接口定義、體系結(jié)構(gòu)、功能特性方面存在很大差別,采取的技術(shù)也有所不同。本節(jié)我們將分別介紹這幾種嵌入式GUI系統(tǒng)。10.2.1Qt/Embedded
Qt/Embedded是著名的Qt庫(kù)開(kāi)發(fā)商TrollTech開(kāi)發(fā)的,是專(zhuān)為嵌入式設(shè)備上的圖形用戶(hù)界面開(kāi)發(fā)而訂做的C++工具包。它是面向嵌入式Linux系統(tǒng)的Qt版本,可以運(yùn)行在多種不同處理器部署的嵌入式Linux操作系統(tǒng)上。
Qt/Embedded的主要特點(diǎn)是:界面美觀、色彩配比好;具有與Qt/Windows和QT/X11完全一致的API接口;具有豐富的控件資源;具有模塊化和可裁減性,用戶(hù)可根據(jù)實(shí)際需要對(duì)其進(jìn)行裁減,以適應(yīng)不同的應(yīng)用環(huán)境。此外,還有很重要的一點(diǎn)就是移植性好,開(kāi)發(fā)者可以將許多基于Qt的XWindow程序非常方便地移植到嵌入式版本,只需重新編譯代碼(而不需對(duì)代碼進(jìn)行修改)即可使程序本地化。它還是面向?qū)ο缶幊痰睦硐氕h(huán)境?,F(xiàn)在,Qt/Embedded被廣泛地應(yīng)用于各種嵌入式產(chǎn)品和設(shè)備中,從消費(fèi)電器(如智能手機(jī)、機(jī)頂盒)到工業(yè)控制設(shè)備(如醫(yī)學(xué)成像設(shè)備、移動(dòng)信息系統(tǒng)等)。但Qt/Embedded對(duì)于系統(tǒng)資源的要求非常高,需要在較大的存儲(chǔ)空間和運(yùn)行空間上才可以運(yùn)行,資源消耗大。另外,Qt/Embedded不是開(kāi)放源碼,若需修改Qt/Embedded并在商業(yè)產(chǎn)品中發(fā)布,則需要支付昂貴的授權(quán)費(fèi)用。
本章后面將重點(diǎn)介紹Qt/Embedded及其編程方法(詳見(jiàn)10.3節(jié))。10.2.2MicroWindows
MicroWindows是由美國(guó)CenturySoftware公司開(kāi)發(fā)的開(kāi)放源碼的嵌入式GUI項(xiàng)目。
MicroWindows是一個(gè)基于典型客戶(hù)端/服務(wù)器體系結(jié)構(gòu)的GUI系統(tǒng),也是基于分層式設(shè)計(jì)的,它允許不同的層可以被重新設(shè)計(jì)以滿(mǎn)足系統(tǒng)實(shí)現(xiàn)的需要。它分為三層:最底層是屏幕、鼠標(biāo)或觸摸屏和鍵盤(pán)的驅(qū)動(dòng)程序,直接與輸入硬件打交道;中間層是一個(gè)可移植的圖形引擎層,通過(guò)最底層提供的服務(wù)提供對(duì)畫(huà)線(xiàn)、填充、裁減區(qū)域、色彩等的支持;最上層是API,提供給圖形化應(yīng)用程序調(diào)用。
MicroWindows支持兩種API:類(lèi)Win32/WinCEAPI和類(lèi)XLIBAPI的Nano-XAPI。這些API與Win32和XWindow窗口系統(tǒng)兼容,使程序可以很容易地從其他系統(tǒng)上移植過(guò)來(lái)。其中比較完備的是Nano-XAPI。Nano-X是基于XWindow的一組Xlib風(fēng)格的API函數(shù)庫(kù)。它被設(shè)計(jì)成是一個(gè)客戶(hù)端/服務(wù)器的環(huán)境,在此模式下應(yīng)用程序與一個(gè)客戶(hù)端的庫(kù)相連,而這個(gè)庫(kù)則通過(guò)一個(gè)Unixsocket與Nano-X服務(wù)器相連。每個(gè)應(yīng)用程序都通過(guò)Unixsocket來(lái)傳遞各種參數(shù),并由服務(wù)端來(lái)完成客戶(hù)端的各種請(qǐng)求。為了提高運(yùn)行速度,還可以通過(guò)共享的內(nèi)存空間來(lái)完成數(shù)據(jù)傳遞。該項(xiàng)目的主要特色在于提供了比較完善的圖形功能,包括一些高級(jí)的功能,比如Alpha混合、三維支持、TrueType字體支持等。它不需要其他圖形系統(tǒng)的支持,可以充分利用Linux提供的FrameBuffer機(jī)制來(lái)進(jìn)行圖形顯示。MicroWindows基本上是用C語(yǔ)言實(shí)現(xiàn)的,因此移植性很強(qiáng),目前已經(jīng)移植到包括ARM在內(nèi)的多種平臺(tái)上,但也同樣導(dǎo)致了系統(tǒng)的運(yùn)行效率不高。
MicroWindows目前開(kāi)發(fā)的重點(diǎn)是底層的圖形引擎,窗口系統(tǒng)和圖形接口方面功能比較欠缺,需進(jìn)一步完善,比如控件或構(gòu)件的實(shí)現(xiàn)還不完備,鍵盤(pán)和鼠標(biāo)等的驅(qū)動(dòng)還不夠完善。同時(shí),MicroWindows的圖形引擎還存在許多問(wèn)題:圖形引擎中存在許多低效算法,未經(jīng)任何優(yōu)化;代碼質(zhì)量較差,參差不齊,影響整體系統(tǒng)的穩(wěn)定性,這也是MicroWindows的發(fā)展陷于停滯狀態(tài)的主要原因。10.2.3MiniGUI
MiniGUI是我國(guó)國(guó)內(nèi)自主開(kāi)發(fā)的、比較成熟的一個(gè)圖形用戶(hù)界面系統(tǒng),它是由許多自由軟件開(kāi)發(fā)人員支持的一個(gè)自由軟件項(xiàng)目,其目標(biāo)是為基于Linux的實(shí)時(shí)嵌入式系統(tǒng)提供一個(gè)輕量級(jí)的圖形用戶(hù)界面支持系統(tǒng)。
MiniGUI是建立在現(xiàn)有成熟的圖形引擎(SVGALib/
LinuxThread)上,支持IntelX86、ARM及PowerPC等硬件平臺(tái),并且可在Linux、eCos與VxWorks等操作系統(tǒng)上運(yùn)行。到目前為止,MiniGUI已經(jīng)發(fā)展成為一個(gè)非常成熟和穩(wěn)定的GUI系統(tǒng),可廣泛應(yīng)用于包括手持設(shè)備、機(jī)頂盒、游戲終端等在內(nèi)的各種高端或者低端的嵌入式系統(tǒng)當(dāng)中。從整體結(jié)構(gòu)看,MiniGUI是分層設(shè)計(jì)的:最底層,GAL和IAL提供底層圖形接口以及鼠標(biāo)和鍵盤(pán)驅(qū)動(dòng);中間層是MiniGUI的核心層,其中包括了窗口系統(tǒng)必不可少的各個(gè)模塊;最上層是API,即編程接口。
MiniGUI有三個(gè)版本:Mini-Threads、MiniGUI-Lite和MiniGUI-Standalone。
(1)?Mini-Threads:基于標(biāo)準(zhǔn)POSIX接口中的pthread庫(kù),適用于功能較為單一的嵌入式系統(tǒng),存在系統(tǒng)健壯性不夠的缺點(diǎn)。
(2)?MiniGUI-Lite:采用多進(jìn)程運(yùn)行方式設(shè)計(jì)的Server/Client架構(gòu),應(yīng)用于多進(jìn)程的應(yīng)用場(chǎng)合,為功能復(fù)雜的嵌入式系統(tǒng)提供了一個(gè)高效、穩(wěn)定的GUI系統(tǒng)。
(3)?MiniGUI-Standalone:以獨(dú)立的進(jìn)程方式運(yùn)行,既不需要多線(xiàn)程,也不需要多進(jìn)程的支持,適應(yīng)范圍比較廣,和其他版本的區(qū)別主要在于編譯鏈接的時(shí)候代用靜態(tài)庫(kù)的方法。
MiniGUI的主要特性如下:
(1)具有完備的多窗口機(jī)制和消息傳遞機(jī)制。
(2)支持多字體和多字符集,支持各種光柵字體和矢量字體,可以實(shí)現(xiàn)在同一個(gè)窗口上同時(shí)顯示不同語(yǔ)種的文字。
(3)支持簡(jiǎn)體中文輸入法,包括全拼、智能拼音、五筆輸入法等。
(4)有豐富的控件資源。
(5)小巧,包括全部功能的庫(kù)文件大小為300KB左右。
(6)可配置,可根據(jù)項(xiàng)目要求進(jìn)行定制配置和編譯。
(7)具有高穩(wěn)定性、高性能,可移植性好,目前MiniGUI可以在XWindow和Linux控制臺(tái)上運(yùn)行。
MiniGUI的缺點(diǎn)是圖形功能尚不完善,應(yīng)用設(shè)計(jì)比較困難。10.2.4OpenGUI
OpenGUI在Linux系統(tǒng)上存在已經(jīng)很長(zhǎng)時(shí)間了,最初的名字叫FastGL,只支持256色的線(xiàn)性顯存模式,但目前也支持其他顯示模式,并且支持多種操作系統(tǒng)平臺(tái),比如MS-DOS、QNX和Linux等,不過(guò)目前只支持X86硬件平臺(tái)。OpenGUI也是一個(gè)公開(kāi)源碼項(xiàng)目。
OpenGUI也分為三層:最底層是由匯編語(yǔ)言編寫(xiě)的快速圖形引擎;中間層提供了圖形繪制API,包括線(xiàn)條、矩形、圓弧等,并且兼容于Borland的BGIAPI;第三層用C++編寫(xiě),提供了完整的GUI對(duì)象集。
OpenGUI比較適合基于X86平臺(tái)的實(shí)時(shí)系統(tǒng),但可移植性稍差。
10.3Qt/Embedded嵌入式圖形開(kāi)發(fā)基礎(chǔ)
本節(jié)將具體介紹基于嵌入式Linux的圖形界面開(kāi)發(fā)環(huán)境Qt/Embedded,并具體描述Qt/Embedded開(kāi)發(fā)環(huán)境的創(chuàng)建和使用方法。10.3.1Qt/Embedded概述
1.關(guān)于Qt
Qt是挪威TrollTech公司的一個(gè)標(biāo)志性產(chǎn)品,它是一個(gè)支持多操作系統(tǒng)平臺(tái)的應(yīng)用程序開(kāi)發(fā)框架,開(kāi)發(fā)語(yǔ)言是C++。Qt開(kāi)發(fā)的最初目的是為跨平臺(tái)的軟件開(kāi)發(fā)者提供統(tǒng)一的、精美的圖形用戶(hù)編程接口,但現(xiàn)在它也提供了統(tǒng)一的網(wǎng)絡(luò)和數(shù)據(jù)庫(kù)操作的編程接口。簡(jiǎn)而言之,Qt是一個(gè)跨平臺(tái)的C++圖形用戶(hù)界面庫(kù),它支持所有Unix系統(tǒng),當(dāng)然也包括Linux,還支持WinNT/Win2k、Win95/98平臺(tái),目前包括Qt、基于FrameBuffer的Qt/Embedded、嵌入式桌面平臺(tái)Qtopia。
Qt是以工具開(kāi)發(fā)包的形式提供給開(kāi)發(fā)者的,這些工具開(kāi)發(fā)包包括了QtDesigner(圖形設(shè)計(jì)器)、Makefile制作工具、字體國(guó)際化工具和Qt的C++類(lèi)庫(kù)等。
Qt的主要特點(diǎn)是:具有豐富的API;優(yōu)良的跨平臺(tái)特性;面向?qū)ο蟮?。Qt不是自由軟件,如果利用Qt編寫(xiě)非免費(fèi)軟件,則需要購(gòu)買(mǎi)他們的License。由于Qt具有面向?qū)ο蟆⒓夹g(shù)成熟等優(yōu)點(diǎn),因此,目前高端嵌入式設(shè)備生產(chǎn)商幾乎都選擇Qt作為開(kāi)發(fā)工具。
其中,Qtopia(全稱(chēng)QtPalmtopEnvironment)是構(gòu)建于Qt/Embedded之上的一個(gè)類(lèi)似桌面系統(tǒng)的應(yīng)用環(huán)境,包含完整的應(yīng)用層、靈活的用戶(hù)界面、窗口操作系統(tǒng)、應(yīng)用程序的啟動(dòng)程序以及開(kāi)發(fā)框架。而Qt/Embedded是Qt的嵌入式Linux版本,它是為嵌入式設(shè)備的圖形用戶(hù)界面開(kāi)發(fā)而訂做的開(kāi)發(fā)工具包,在世界各地被廣泛使用。除了在商業(yè)上的許多應(yīng)用以外,Qt/Embedded還是為小型設(shè)備提供Qtopia應(yīng)用環(huán)境的基礎(chǔ)。Qt/Embedded以簡(jiǎn)潔的系統(tǒng)、可視化的表單設(shè)計(jì)和翔實(shí)的API讓編寫(xiě)代碼變得愉快和舒暢。
2.?Qt/Embedded的體系結(jié)構(gòu)
Qt/Embedded是Trolltech公司開(kāi)發(fā)的面向嵌入式系統(tǒng)的Qt版本,與X11版本的Qt在最大程度上接口兼容。Qt/Embedded包括類(lèi)庫(kù)以及支持嵌入式開(kāi)發(fā)的工具等。Qt/Embedded類(lèi)庫(kù)完全采用C++封裝,并且有著豐富的控件資源以及較好的可移植性。Qt/Embedded的實(shí)現(xiàn)結(jié)構(gòu)如圖10-2所示。圖10-2Qt/Embedded的實(shí)現(xiàn)結(jié)構(gòu)
QWSServer是一個(gè)圖形事件服務(wù)類(lèi),它提供了在Qt/Embedded中服務(wù)器特定的功能,當(dāng)運(yùn)行Qt/Embedded應(yīng)用程序時(shí),這個(gè)應(yīng)用程序可作為一個(gè)服務(wù)器運(yùn)行或連接到一個(gè)存在的服務(wù)器。如果一個(gè)服務(wù)器運(yùn)行,則一些附加操作通過(guò)QWSServer類(lèi)來(lái)提供。
Qt/Embedded的底層圖形引擎基于FrameBuffer。如10.2節(jié)中所述,F(xiàn)rameBuffer(幀緩沖)是一種驅(qū)動(dòng)程序接口,用戶(hù)可以把FrameBuffer看成是一塊內(nèi)存,既可以從這塊內(nèi)存中讀取數(shù)據(jù),也可以向其中寫(xiě)入數(shù)據(jù),而寫(xiě)操作立即反映在屏幕上。為運(yùn)行Qt/Embedded,嵌入式Linux內(nèi)核要支持FrameBuffer。
Qt/Embedded同樣是Server/Client結(jié)構(gòu),Qt/Embedded通過(guò)QtAPI與LinuxI/O設(shè)備的直接交互,成為嵌入式Linux端口。Qt/Embedded提供自身的輕量級(jí)窗口系統(tǒng),比使用XLib和XWindow更加緊湊,因?yàn)樗恍枰粋€(gè)XWindowServer或是XLib庫(kù),它在底層摒棄了XLib,并采用幀緩沖(FrameBuffer)作為底層圖形接口。圖10-3為Qt/Embedded與Qt/X11的關(guān)系圖。圖10-3Qt/Embedded與Qt/X11的關(guān)系圖同Qt/X11相比,Qt/Embedded最顯著的效果就是減少了內(nèi)存消耗。因此,運(yùn)行Qt/Embedded所需的系統(tǒng)資源可以很小,相對(duì)X窗口下的嵌入解決方案而言,Qt/Embedded只要求一個(gè)較小的存儲(chǔ)空間(Flash)和內(nèi)存。
3.?Qt/Embedded的開(kāi)發(fā)工具
Qt/Embedded提供許多支持嵌入式開(kāi)發(fā)的工具,其中兩個(gè)非常重要的Qt工具就是:qmake和QtDesigner(Qt圖形設(shè)計(jì)器)。
qmake是一個(gè)為編譯Qt/Embedded庫(kù)和應(yīng)用而提供的Makefile生成器,可以為Qt/Embedded鏈接庫(kù)和應(yīng)用程序生成Makefile文件。qmake可以根據(jù)一個(gè)項(xiàng)目文件(.pro)產(chǎn)生多種平臺(tái)下的Makefile文件,使應(yīng)用程序方便地在多種平臺(tái)間移植。
QtDesigner是一個(gè)具有可視化用戶(hù)接口的設(shè)計(jì)工具。Qt的應(yīng)用程序可以完全用源代碼編寫(xiě),也可以使用QtDesigner來(lái)加速開(kāi)發(fā)工作。QtDesigner使用可視化的方式來(lái)設(shè)計(jì)對(duì)話(huà)框和窗口,而不用手工編寫(xiě)代碼。在QtDesigner中還可以使用布局管理器來(lái)平滑地設(shè)置窗口部件的布局,使用代碼編寫(xiě)器編寫(xiě)代碼。qmake和QtDesigner是完全整合在一起的。
4.?Qt/Embedded的窗口系統(tǒng)
Qt/Embedded包括了它自身的窗口系統(tǒng)。一個(gè)Qt/Embedded窗口系統(tǒng)包含了一個(gè)或多個(gè)進(jìn)程,其中的一個(gè)進(jìn)程可作為服務(wù)器。這個(gè)服務(wù)進(jìn)程會(huì)分配客戶(hù)顯示區(qū)域,以及產(chǎn)生鼠標(biāo)和鍵盤(pán)事件。這個(gè)服務(wù)進(jìn)程還能夠提供輸入方法和一個(gè)用戶(hù)接口給運(yùn)行起來(lái)的客戶(hù)應(yīng)用程序。這個(gè)服務(wù)進(jìn)程其實(shí)就是一個(gè)有某些額外權(quán)限的客戶(hù)進(jìn)程。任何程序都可以在命令行上加上“-qws”的選項(xiàng)來(lái)把它作為一個(gè)服務(wù)器運(yùn)行??蛻?hù)與服務(wù)器之間的通信使用共享內(nèi)存的方法,通信量應(yīng)該保持最小,例如客戶(hù)進(jìn)程直接訪(fǎng)問(wèn)幀緩沖來(lái)完成全部的繪制操作,而不會(huì)通過(guò)服務(wù)器,客戶(hù)程序需要負(fù)責(zé)繪制它們自己的標(biāo)題欄和其他式樣。這就是Qt/Embedded庫(kù)內(nèi)部的處理過(guò)程。
客戶(hù)可以使用QCOP通道交換消息。服務(wù)進(jìn)程簡(jiǎn)單地廣播QCOP消息給所有監(jiān)聽(tīng)指定通道的應(yīng)用進(jìn)程,接著應(yīng)用進(jìn)程可以把一個(gè)插槽連接到一個(gè)負(fù)責(zé)接收的信號(hào)上,從而對(duì)消息做出響應(yīng)。消息的傳遞通常伴隨著二進(jìn)制數(shù)據(jù)的傳輸,這是通過(guò)一個(gè)QDataStream類(lèi)的序列化過(guò)程來(lái)實(shí)現(xiàn)的。QProcess類(lèi)提供了另外一種異步進(jìn)程間通信的機(jī)制。它用于啟動(dòng)一個(gè)外部的程序并且通過(guò)寫(xiě)一個(gè)標(biāo)準(zhǔn)的輸入和讀取外部程序的標(biāo)準(zhǔn)輸出及錯(cuò)誤碼來(lái)與它們通信。
5.字體
Qt/Embedded支持四種不同的字體格式:TrueType字體(TTF)、PostscriptType1字體(TYPE1)、位圖發(fā)布字體(BDF)和Qt的預(yù)呈現(xiàn)(Pre-rendered)字體(QPF)。Qt還可以通過(guò)增加QFontFactory的子類(lèi)來(lái)支持其他字體,也可以支持以插件方式出現(xiàn)的反別名字體。
每個(gè)TTF或者TYPE1類(lèi)型的字體首次被使用時(shí),這些字體的字形都會(huì)以指定的大小被預(yù)先呈現(xiàn)出來(lái),呈現(xiàn)的結(jié)果會(huì)以QPF的格式被保存下來(lái),這樣可以節(jié)省內(nèi)存和CPU處理時(shí)間。QPF文件包含了一些必要的字體,這些字體可以通過(guò)makeqpf工具取得或者通過(guò)運(yùn)行程序時(shí)加上“savefonts”選項(xiàng)獲取。如果應(yīng)用程序中使用到的字體都是QPF格式,那么Qt/Embedded將被重新配置,并排除對(duì)TTF和TYPE1類(lèi)型的字體的編譯,這樣就可以減少Q(mào)t/Embedded的庫(kù)的大小和存儲(chǔ)字體的空間。
Qt/Embedded的字體通常包括Unicode字體的一部分子集,如ASII和Latin-1。一個(gè)完整的16點(diǎn)陣的Unicode字體的存儲(chǔ)空間通常超過(guò)1MB,我們應(yīng)盡可能存儲(chǔ)一個(gè)字體的子集,而不是存儲(chǔ)所有的字,例如在用戶(hù)的應(yīng)用中,用戶(hù)僅僅需要以Cappuccino字體、粗體的方式顯示產(chǎn)品的名稱(chēng),但是用戶(hù)卻有一個(gè)包含了全部字形的字體文件。
6.輸入設(shè)備和輸入方法
Qt/Embedded3.0支持以下幾種鼠標(biāo)協(xié)議:BusMouse、IntelliMouse、Microsoft和MouseMan,支持NECVr41XX和iPAQ的觸摸屏,還支持標(biāo)準(zhǔn)的101鍵盤(pán)和Vr41XX按鍵。若通過(guò)子類(lèi)化QWSKeyboardHandler可以讓Qt/Embedded支持更多的客戶(hù)鍵盤(pán)和其他的非指示設(shè)備。
在一個(gè)無(wú)鍵盤(pán)的設(shè)備上,輸入法成了唯一的輸入字符的手段。Qtopia提供了4種輸入方法:筆跡識(shí)別器、Unicode鍵盤(pán)、圖形化的標(biāo)準(zhǔn)鍵盤(pán)以及字典式提取鍵盤(pán)。這些鍵盤(pán)的樣式如圖10-4所示。圖10-4Qtopia的4種輸入方法(a)筆跡識(shí)別器;(b)?Unicode鍵盤(pán);(c)標(biāo)準(zhǔn)鍵盤(pán);(d)字典式提取鍵盤(pán)10.3.2創(chuàng)建Qt/Embedded開(kāi)發(fā)環(huán)境
一般來(lái)說(shuō),基于Qt/Embedded開(kāi)發(fā)的應(yīng)用程序最終會(huì)發(fā)布到安裝有嵌入式Linux操作系統(tǒng)的小型設(shè)備上,所以使用裝有Linux操作系統(tǒng)的PC或者工作站來(lái)完成Qt/Embedded開(kāi)發(fā)是最理想的環(huán)境,盡管Qt/Embedded也可以安裝在Unix和Windows系統(tǒng)上。
下面介紹在一臺(tái)裝有Linux操作系統(tǒng)的機(jī)器上建立Qt/Embedded開(kāi)發(fā)環(huán)境的方法。
1.準(zhǔn)備軟件安裝包
首先,準(zhǔn)備三個(gè)軟件安裝包:tmake工具安裝包、Qt/Embedded安裝包和Qt的X11版安裝包(注意:QtforX11的版本應(yīng)比Qt/Embedded的版本舊)。
我們以下列版本的安裝包逐步介紹Qt/Embedded開(kāi)發(fā)環(huán)境的創(chuàng)建過(guò)程:
(1)?tmake1.11:用于生成Qt/Embedded應(yīng)用工程的Makefile文件。
(2)?Qt/Embedded2.3.7:Qt/Embedded安裝包。
(3)?Qt2.3.2forX11:Qt的X11版安裝包,用于產(chǎn)生X11開(kāi)發(fā)環(huán)境所需要的兩個(gè)工具。
2.安裝tmake
在Linux命令模式下運(yùn)行以下命令:
tarxfztmake-1.11.tar.gz
exportTMAKEDIR=$PWD/tmake-1.11
exportTMAKEPATH=$TMAKEDIR/lib/qws/linux-x86-g++
exportPATH=$TMAKEDIR/bin:$PATH
3.安裝Qt/Embedded2.3.7
在Linux命令模式下運(yùn)行以下命令:
tarxfzqt-embedded-2.3.7.tar.gz
cdqt-2.3.7
exportQTDIR=$PWD
exportQTEDIR=$QTDIR
exportPATH=$QTDIR/bin:$PATH
exportLD_LIBRARY_PATH=$QTDIR/lib:$LD_
LIBRARY_PATH
./configure-qconfig-qvfb-depths4,8,16,32
makesub-src
cd..命令“./configure-qconfig-qvfb-depths4,8,16,32”指定Qt嵌入式開(kāi)發(fā)包生成虛擬緩沖幀工具qvfb,并支持4、8、16、32位的顯示顏色深度。另外,還可以在configure的參數(shù)中添加-system-jpeg和gif,使Qt/Embedded平臺(tái)能支持jpeg、gif格式的圖形。
命令“makesub-src”指定按精簡(jiǎn)方式編譯開(kāi)發(fā)包,也就是說(shuō),有些Qt類(lèi)未被編譯。Qt嵌入式開(kāi)發(fā)包有5種編譯范圍的選項(xiàng),使用這些選項(xiàng),可控制Qt生成的庫(kù)文件的大小,但是用戶(hù)應(yīng)用時(shí)所使用到的一些Qt類(lèi)將可能因此在Qt的庫(kù)中找不到鏈接。編譯選項(xiàng)的具體用法可通過(guò)“./configure-help”命令查看。
4.安裝Qt/X112.3.2
在Linux命令模式下運(yùn)行以下命令:10.3.3Qt/Embedded的使用
1.信號(hào)與插槽(signals/slots)機(jī)制
Trolltech創(chuàng)立了一種新的機(jī)制—信號(hào)與插槽(signals/slots)機(jī)制。信號(hào)與插槽機(jī)制是Qt的重要特征,它是一種強(qiáng)有力的對(duì)象間通信機(jī)制,它完全可以取代原始的回調(diào)和消息映射機(jī)制。信號(hào)與插槽是迅速的、類(lèi)型安全的、健壯的、完全面向?qū)ο蟛⒂肅++來(lái)實(shí)現(xiàn)的一種機(jī)制。
1)原理
原始的回調(diào)函數(shù)機(jī)制是指,將某段響應(yīng)代碼和某個(gè)按鈕的動(dòng)作相關(guān)聯(lián),把響應(yīng)代碼寫(xiě)成一個(gè)函數(shù),然后把這個(gè)函數(shù)的地址指針傳給按鈕,當(dāng)那個(gè)按鈕被按下時(shí),這個(gè)函數(shù)就會(huì)被執(zhí)行。這種方式存在兩個(gè)問(wèn)題:一是,回調(diào)函數(shù)被執(zhí)行時(shí)所傳遞進(jìn)來(lái)的函數(shù)參數(shù)不能確保是否正確,容易造成進(jìn)程崩潰;二是,回調(diào)這種方式緊緊地綁定了圖形用戶(hù)接口的功能元素,因而很難把開(kāi)發(fā)獨(dú)立地分類(lèi)。然而,Qt的信號(hào)與插槽機(jī)制是不同的。Qt的窗口在事件發(fā)生后會(huì)激發(fā)信號(hào)。程序員通過(guò)建立一個(gè)函數(shù)(稱(chēng)做一個(gè)插槽),然后調(diào)用connect()函數(shù)把這個(gè)插槽和一個(gè)信號(hào)連接起來(lái),這樣就完成了一個(gè)事件和響應(yīng)代碼的連接。例如,如果一個(gè)退出按鈕的clicked()信號(hào)被連接到了一個(gè)應(yīng)用的退出函數(shù)quit()插槽,那么一個(gè)用戶(hù)點(diǎn)擊退出鍵將使應(yīng)用程序終止運(yùn)行。此連接過(guò)程用代碼寫(xiě)出來(lái)就是:
connect(button,SIGNAL(clicked()),qApp,SLOT(quit()));信號(hào)與插槽機(jī)制(如圖10-5所示)中的一個(gè)對(duì)象的信號(hào)可以被多個(gè)不同的插槽連接,而多個(gè)信號(hào)也可以被連接到相同的插槽。當(dāng)信號(hào)和插槽被連接起來(lái)時(shí),應(yīng)當(dāng)確保它們的參數(shù)類(lèi)型是相同的,如果插槽的參數(shù)個(gè)數(shù)小于和它連接在一起的信號(hào)的參數(shù)個(gè)數(shù),那么從信號(hào)傳遞插槽的多余的參數(shù)將被忽略。圖10-5信號(hào)與插槽機(jī)制
2)特性
(1)可開(kāi)發(fā)出代碼重用的類(lèi),因?yàn)樗灰箢?lèi)之間互相知道細(xì)節(jié)。
(2)類(lèi)型安全的,因?yàn)樗跃娴姆绞綀?bào)告類(lèi)型錯(cuò)誤,而不會(huì)使系統(tǒng)產(chǎn)生崩潰。
(3)面向?qū)ο蟮模驗(yàn)樗耆捎肅++來(lái)實(shí)現(xiàn),利用了C++面向?qū)ο蟮奶卣鳌?/p>
3)元對(duì)象編譯器(MetaObjectCompiler,MOC)
信號(hào)與插槽機(jī)制是以純C++代碼來(lái)實(shí)現(xiàn)的,實(shí)現(xiàn)的過(guò)程使用了Qt開(kāi)發(fā)工具包提供的預(yù)處理器和元對(duì)象編譯器(MOC)。MOC的作用是讀取應(yīng)用程序的頭文件,并產(chǎn)生支持信號(hào)與插槽的必要的代碼。開(kāi)發(fā)者沒(méi)必要編輯或是瀏覽這些自動(dòng)產(chǎn)生的代碼,當(dāng)有需要時(shí),qmake生成的Makefile文件里會(huì)顯式運(yùn)行MOC的規(guī)則。除了可以處理信號(hào)與插槽機(jī)制之外,MOC還支持翻譯機(jī)制、屬性系統(tǒng)和運(yùn)行時(shí)的信息。
4)實(shí)例
如果一個(gè)類(lèi)要使用信號(hào)與插槽機(jī)制,它就必須是從QObject或者QObject的子類(lèi)繼承,而且在類(lèi)的定義中必須加上Q_OBJECT宏。其中,信號(hào)被定義在類(lèi)的信號(hào)部分,而插槽則定義在publicslots、protectedslots或者privateslots部分。下面定義了一個(gè)使用到信號(hào)與插槽機(jī)制的類(lèi):
BankAccount類(lèi)和大部分C++的類(lèi)一樣。其中,有一個(gè)信號(hào)balanceChanged(),聲明了它在BankAccount類(lèi)的成員curBalance的值被改變時(shí)產(chǎn)生。信號(hào)不需要被實(shí)現(xiàn),當(dāng)信號(hào)被激發(fā)時(shí),和該信號(hào)連接的插槽將被執(zhí)行。插槽函數(shù)setBalance(intnewBalance)的實(shí)現(xiàn)代碼如下:其中:“emitbalanceChanged(curBalance);”的作用是當(dāng)curBalance的值被改變后,將新的curBalance的值作為參數(shù)去激活balanceChanged()信號(hào)。對(duì)于關(guān)鍵詞“emit”,它和信號(hào)、插槽一樣是由Qt提供的,這些關(guān)鍵詞都會(huì)被C++的預(yù)處理機(jī)制轉(zhuǎn)換為C++代碼。
2.窗體(Qwidget及其子類(lèi))
一個(gè)窗體可以包含很多的子窗體,子窗體可以顯示在父窗體的客戶(hù)區(qū)。而一個(gè)沒(méi)有父窗體的窗體我們稱(chēng)之為頂級(jí)窗體(一個(gè)“窗口”)。一個(gè)窗體通常由一個(gè)邊框和標(biāo)題欄來(lái)裝飾。
Qt并未對(duì)窗體有什么限制,任何類(lèi)型的窗體都可以是頂級(jí)窗體,也可以是別的窗體的自窗體。同時(shí),標(biāo)簽、消息框和工具欄等可以使用任何顏色、任何字體和語(yǔ)言。Qt窗體使用起來(lái)很靈活,它可以被子類(lèi)化,以滿(mǎn)足客戶(hù)不同的需求。
窗體是Qwidget類(lèi)或其子類(lèi)的實(shí)例,客戶(hù)自己的窗體類(lèi)需要從Qwidget的子類(lèi)繼承(見(jiàn)圖10-6)。圖10-6Qwidget類(lèi)的繼承圖例如:繪制一個(gè)模擬的時(shí)鐘,顯示當(dāng)前時(shí)間,并自動(dòng)地更新時(shí)間。
(1)在“analogclock.h”頭文件中,定義AnalogClock,代碼如下:
AnalogClock類(lèi)繼承了Qwidget,它有一個(gè)典型的窗體類(lèi)構(gòu)造函數(shù),這個(gè)函數(shù)有父窗口對(duì)象指針和名字指針兩個(gè)參數(shù)。
timerEvent()函數(shù)是從QObject(Qwidget的父類(lèi))對(duì)象繼承而來(lái)的,這個(gè)函數(shù)會(huì)被系統(tǒng)定期調(diào)用。paintEvent()函數(shù)是從QWidget繼承而來(lái)的,并且當(dāng)窗體需要重畫(huà)時(shí),這個(gè)函數(shù)就會(huì)被調(diào)用。timerEvent()和paintEvent()函數(shù)是“事件句柄”的兩個(gè)例子。應(yīng)用對(duì)象以重載父類(lèi)對(duì)象的虛擬函數(shù)events(QEventobjects)的形式接收系統(tǒng)的事件。大約有超過(guò)50個(gè)的系統(tǒng)事件是較常用的,例如MouseButtonPress、MouseButtonRelease、KeyPress、KeyRelease、Paint、Resize和Close。
(2)?analogclock.cpp文件是定義在analogclock.h中的函數(shù)的實(shí)現(xiàn)源文件,代碼如下:構(gòu)造函數(shù)設(shè)置窗口的尺寸大小為100×100,并且告訴系統(tǒng)每隔12秒調(diào)用一次timerEvent()函數(shù),從而對(duì)模擬鐘的窗體進(jìn)行刷新。
在timerEvent()函數(shù)中,通過(guò)調(diào)用QWidget的函數(shù)update()就可以告訴Qt,窗體需要立即重畫(huà),緊接著Qt就會(huì)產(chǎn)生一個(gè)繪制事件并且調(diào)用paintEvent()函數(shù)。
在paintEvent()函數(shù)中,一個(gè)Qpainter對(duì)象用于在窗體上繪制12個(gè)刻度以及分針、時(shí)針。Qpainter類(lèi)提供了一種統(tǒng)一的方式用于繪制窗體、位圖、矢量圖等,它提供了繪制點(diǎn)、線(xiàn)、橢圓、多邊形、弧、貝塞爾曲線(xiàn)等功能。一個(gè)Qpainter的坐標(biāo)系可以被轉(zhuǎn)變、縮放、旋轉(zhuǎn)和剪切,這樣對(duì)象就可以根據(jù)它在窗口或者窗體上的位置繪制出一個(gè)剪切的視圖。剪切可以使窗體繪制時(shí)減少閃爍。使用QPainter的子類(lèi)QdirectPainter可以鎖定和直接訪(fǎng)問(wèn)幀緩沖區(qū)域。
(3)文件analogclock.h與analogclock.cpp完全地定義和實(shí)現(xiàn)了AnalogClock客戶(hù)窗體類(lèi),這個(gè)窗體是現(xiàn)在就可以使用的。
3.主窗口(QMainWindow類(lèi))
QMainWindow類(lèi)是為應(yīng)用的主窗口提供了一個(gè)擺放相關(guān)窗體的框架。
通常情況下,主窗口的頂部是一個(gè)菜單欄,底部有一個(gè)狀態(tài)欄,中間區(qū)域可以包含其他的窗體,而菜單欄下方放置著一個(gè)工具欄。另外,當(dāng)鼠標(biāo)在窗體的某些位置移動(dòng)時(shí),還會(huì)出現(xiàn)一些旁述的按鈕,如“提示欄”和“這是什么”幫助按鈕等。其中,工具欄可以被拖放到一個(gè)停靠的位置,形成一個(gè)浮動(dòng)的工具面板。
1)菜單欄(QmenuBar類(lèi))
QmenuBar類(lèi)實(shí)現(xiàn)了一個(gè)菜單欄,它會(huì)自動(dòng)地設(shè)置幾何尺寸并在它的父窗體的頂部顯示出來(lái),如果父窗體的寬度不夠?qū)挘灾虏荒茱@示一個(gè)完整的菜單欄,那么菜單欄將會(huì)分為多行顯示出來(lái)。Qt內(nèi)置的布局管理能夠自動(dòng)地調(diào)整菜單欄。Qt的菜單系統(tǒng)是非常靈活的,菜單項(xiàng)可以被動(dòng)態(tài)地使能、失效、添加或者刪除。通過(guò)子類(lèi)化QcustomMenuItem,我們可以建立客戶(hù)化外觀和功能的菜單項(xiàng)。
QpopupMenu(彈出式菜單)類(lèi)以垂直列表的方式顯示菜單項(xiàng),它可以是單個(gè)的,也可以是以菜單欄的方式出現(xiàn)的,或者是以別的彈出式菜單的子菜單出現(xiàn)的。每個(gè)菜單項(xiàng)可以有一個(gè)圖標(biāo)、一個(gè)復(fù)選框和一個(gè)加速器(快捷鍵)。菜單項(xiàng)通常對(duì)應(yīng)一個(gè)動(dòng)作(例如存盤(pán)),分隔器通常顯示成一條豎線(xiàn),它用于把一組相關(guān)聯(lián)的動(dòng)作菜單分立成組。例如,建立一個(gè)包含有New、Open和Exit菜單項(xiàng)的文件菜單:當(dāng)一個(gè)菜單項(xiàng)被選中時(shí),和它相關(guān)的插槽將被執(zhí)行。加速器(快捷鍵)很少在一個(gè)沒(méi)有鍵盤(pán)輸入的設(shè)備上使用,Qt/Embedded的典型配置并未包含對(duì)加速器的支持。上面出現(xiàn)的“&New”代碼的意思是在桌面機(jī)器上以“New”的方式顯示出來(lái),但是在嵌入式設(shè)備上,它只會(huì)顯示為“New”。
2)工具欄(QtoolButton類(lèi))
QtoolButton類(lèi)實(shí)現(xiàn)了一個(gè)帶有圖標(biāo)、三維邊框和可選標(biāo)簽的工具欄按鈕。切換工具欄按鈕具有開(kāi)、關(guān)的特征,其他的按鈕則執(zhí)行相應(yīng)命令。不同的圖標(biāo)用來(lái)表示按鈕的活動(dòng),無(wú)效、使能模式,或者是開(kāi)或關(guān)的狀態(tài)。如果用戶(hù)僅為按鈕指定了一個(gè)圖標(biāo),那么Qt會(huì)使用可視提示來(lái)表現(xiàn)按鈕不同的狀態(tài),例如按鈕失效時(shí)顯示灰色。
工具欄按鈕通常以一排的形式顯示在工具欄上。對(duì)于一個(gè)有幾組工具欄的應(yīng)用,用戶(hù)可以隨便地到處移動(dòng)這些工具欄,工具欄差不多可以包含所有的窗體,例如QComboBoxes和QspinBoxes。
3)旁述
Qt提供了兩種旁述的方式:“提示欄”和“這是什么”幫助按鈕。
(1)“提示欄”按鈕:通常是小的黃色的矩形,當(dāng)鼠標(biāo)在窗體的一些位置游動(dòng)時(shí),它就會(huì)自動(dòng)出現(xiàn),主要用于解釋工具欄按鈕,特別是那些缺少文字標(biāo)簽說(shuō)明的工具欄按鈕的用途。
例如,設(shè)置一個(gè)“存盤(pán)”按鈕提示的代碼:
QToolTip::add(saveButton,“Save”);
當(dāng)提示字符出現(xiàn)之后,用戶(hù)還可以在狀態(tài)欄顯示更詳細(xì)的文字說(shuō)明。
(2)“這是什么”幫助按鈕:通常指在靠近應(yīng)用窗口的關(guān)閉按鈕“×”附近看到的“?”符號(hào)的小按鈕。它同“提示欄”按鈕有些相似,只不過(guò)“提示欄”按鈕是要鼠標(biāo)點(diǎn)擊了才會(huì)顯示旁述。對(duì)于一些沒(méi)有鼠標(biāo)的設(shè)備,也許就需要使用“這是什么”幫助按鈕。此外,“這是什么”幫助按鈕按下后顯示的提示信息一般比“提示欄”要多一些。
例如,設(shè)置一個(gè)存盤(pán)按鈕的“這是什么”文本提示信息:
QWhatsThis::add(saveButton,"Savesthecurrentfile.");
QToolTip和QWhatsThis類(lèi)提供了虛擬函數(shù)以供開(kāi)發(fā)者重新實(shí)現(xiàn)更多的特定的用途。Qtopia并未使用上述提及的兩種旁述機(jī)制。它在應(yīng)用窗口的標(biāo)題欄上放置一個(gè)“?”符號(hào)的按鈕來(lái)代替上述的旁述機(jī)制,這個(gè)“?”按鈕可以啟動(dòng)一個(gè)瀏覽器來(lái)顯示和當(dāng)前應(yīng)用相關(guān)的HTML頁(yè)面。Qtopia使用按下和握住的姿態(tài)來(lái)調(diào)用上下文菜單與屬性對(duì)話(huà)框。
4)動(dòng)作(QAction類(lèi))
應(yīng)用程序通常提供給用戶(hù)幾種不同的方式去執(zhí)行特別的動(dòng)作。例如,大部分應(yīng)用提供了一個(gè)“Save”動(dòng)作給用于存盤(pán)的菜單(File|Save)以及工具欄(一個(gè)“軟盤(pán)”圖標(biāo)的工具欄按鈕)和快捷鍵(Ctrl+S)。
QAction類(lèi)可以讓上述過(guò)程變得簡(jiǎn)潔,它允許程序員在一個(gè)地方定義一個(gè)動(dòng)作,然后把這個(gè)動(dòng)作加入到菜單或者工具欄。
QAction類(lèi)可以確保菜單的狀態(tài)與工具欄按鈕的狀態(tài)保持一致,必要時(shí)還可顯示提示欄。使一個(gè)動(dòng)作(Action)失效將導(dǎo)致和該動(dòng)作相關(guān)聯(lián)的菜單項(xiàng)以及工具按鈕的失效。同樣地,如果用戶(hù)切換一個(gè)工具按鈕的狀態(tài),那么相關(guān)的菜單項(xiàng)也會(huì)跟著被選中或不選中。例如,實(shí)現(xiàn)一個(gè)“Save”菜單項(xiàng)和一個(gè)“Save”工具按鈕:
4.對(duì)話(huà)框
Qt提供了許多現(xiàn)成的包含了實(shí)用的靜態(tài)函數(shù)的對(duì)話(huà)框類(lèi)。
如圖10-7所示,QmessageBox類(lèi)是一個(gè)用于向用戶(hù)提供信息或是給用戶(hù)進(jìn)行一些簡(jiǎn)單選擇(例如“yes”或“no”)的對(duì)話(huà)框類(lèi)。QprogressDialog對(duì)話(huà)框包含了一個(gè)進(jìn)度欄和一個(gè)“Cancel”按鈕。Qwizard類(lèi)提供了一個(gè)向?qū)?duì)話(huà)框的框架。
Qt提供的對(duì)話(huà)框還包括QColorDialog、QFileDialog、QFontDialog和QprintDialog。圖10-7QmessageBox與QprogressDialog對(duì)話(huà)框
5.窗體的布局管理
布局管理的作用是組織管理父窗體區(qū)域內(nèi)的子窗體。它可以自動(dòng)設(shè)置子窗體的位置和大小,并可判斷出一個(gè)頂級(jí)窗體的最小和缺省的尺寸,當(dāng)窗體的字體或內(nèi)容變化后,它可以重置一個(gè)窗體的布局。布局管理使得圖形用戶(hù)界面的開(kāi)發(fā)高效而簡(jiǎn)便,也使得提供部分用戶(hù)接口組件(如輸入法和任務(wù)欄)變得更容易。
Qt提供了三種用于布局管理的類(lèi):QHBoxLayout、QVBoxLayout和QGridLayout。QHBoxLayout布局管理把窗體按照水平方向從左至右排成一行;QVBoxLayout布局管理把窗體按照垂直方向從上至下排成一列;QGridLayout布局管理以網(wǎng)格的方式來(lái)排列窗體,一個(gè)窗體可以占據(jù)多個(gè)網(wǎng)格。三者的布局效果見(jiàn)圖10-8。
例如,建立兩個(gè)如圖10-9所示的不同尺寸的對(duì)話(huà)框。圖10-8QHBoxLayout、QVBoxLayout和QGridLayout的布局效果圖10-9兩個(gè)不同尺寸
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024年蘇州托普信息職業(yè)技術(shù)學(xué)院馬克思主義基本原理概論期末考試題含答案解析(奪冠)
- 2025年景德鎮(zhèn)學(xué)院馬克思主義基本原理概論期末考試模擬題帶答案解析(必刷)
- 2025年浙江同濟(jì)科技職業(yè)學(xué)院?jiǎn)握新殬I(yè)傾向性測(cè)試題庫(kù)帶答案解析
- 2025年四川工商職業(yè)技術(shù)學(xué)院?jiǎn)握新殬I(yè)技能考試題庫(kù)帶答案解析
- 四川省成都市郫都區(qū)2024-2025學(xué)年高三下學(xué)期階段性檢測(cè)(三)生物試題(解析版)
- 2025年射陽(yáng)縣招教考試備考題庫(kù)帶答案解析(奪冠)
- 2025年昭平縣幼兒園教師招教考試備考題庫(kù)帶答案解析(奪冠)
- 2025年南京審計(jì)大學(xué)金審學(xué)院馬克思主義基本原理概論期末考試模擬題帶答案解析(奪冠)
- 2025年武寧縣招教考試備考題庫(kù)含答案解析(奪冠)
- 赤峰2025年內(nèi)蒙古赤峰市阿魯科爾沁旗醫(yī)院招聘19人筆試歷年參考題庫(kù)附帶答案詳解
- 2025-2026學(xué)年江蘇省連云港市部分學(xué)校高三上學(xué)期10月月考?xì)v史試題(解析版)
- 道路交通安全警示教育培訓(xùn)
- 獸藥使用法律法規(guī)學(xué)習(xí)材料
- 記賬實(shí)操-村會(huì)計(jì)賬務(wù)處理分錄SOP
- 市政工程述職報(bào)告
- 公文寫(xiě)作實(shí)例培訓(xùn)
- 2026年中考語(yǔ)文一輪復(fù)習(xí):統(tǒng)編教材古詩(shī)詞曲鑒賞85篇 ??急乇持R(shí)點(diǎn)匯編
- 海事組織航標(biāo)知識(shí)培訓(xùn)課件
- 網(wǎng)吧安全生產(chǎn)知識(shí)培訓(xùn)課件
- 2025-2030高端汽車(chē)品牌營(yíng)銷(xiāo)策略與消費(fèi)者畫(huà)像分析報(bào)告
- 心肺復(fù)蘇指南2025版
評(píng)論
0/150
提交評(píng)論