詳解基于Qt Embedded和Qtopia GUI設(shè)計
詳解基于Qt Embedded和Qtopia GUI設(shè)計是本文要介紹的內(nèi)容,介紹了Qt Embedded和Qtopia的體系結(jié)構(gòu)及其交叉編譯過程與安裝過程,重點講述了如何實現(xiàn)Qt Embedded下的應(yīng)用程序以及如何將應(yīng)用程序移植到Qtopia桌面系統(tǒng)。本文介紹的方法在筆者的開發(fā)平臺上都做過驗證。
隨著當(dāng)前各種手持設(shè)備、無線設(shè)備及信息家電等嵌入式產(chǎn)品的迅猛發(fā)展,相應(yīng)的嵌入式軟硬件設(shè)計技術(shù)也在發(fā)生深刻的變化。如今,越來越多的嵌入式終端需要一個圖形化的人機接口界面(GUI),良好的人機接口界面是嵌入式系統(tǒng)設(shè)計的一個關(guān)鍵技術(shù),能夠極大地提高人機交互的效率。本文詳細(xì)闡述了在自行開發(fā)的嵌入式主板上實現(xiàn)某平臺的圖形顯示終端過程。
系統(tǒng)平臺介紹
根據(jù)系統(tǒng)設(shè)計需求,本文目的是實現(xiàn)一個具有圖形接口界面的嵌入式顯示終端,該系統(tǒng)使用嵌入式系統(tǒng)設(shè)計技術(shù)。硬件上,使用自行開發(fā)的基于Samsung S3C2440A CPU的目標(biāo)板,該CPU使用arm920T內(nèi)核,其主頻可達(dá)400Mhz;在軟件上,選擇嵌入式linux為操作系統(tǒng),因為它源碼開放,而且穩(wěn)定性與安全性較高。
整個系統(tǒng)軟件由引導(dǎo)裝載程序(uboot)、 設(shè)備驅(qū)動(包括幀緩存fb)、嵌入式Linux內(nèi)核、文件系統(tǒng)(yaffs)、基于QT/Embedded和Qtopia的用戶圖形界面以及應(yīng)用程序組成,系統(tǒng)平臺結(jié)構(gòu)如圖(1)所示。
圖(1) 系統(tǒng)平臺軟件結(jié)構(gòu)圖
Qt Embedded和Qtopia 介紹及其開發(fā)環(huán)境的建立
目前嵌入式Linux的主流GUI系統(tǒng)主要有MiniGUI、Microwindows、OpenGUI、Qt/Embedded,這些GUI在接口定義、體系結(jié)構(gòu)、功能特性存在很大差別,采取的技術(shù)路線也有所不同[1]。MiniGUI是建立在比較成熟的圖形引擎之上,開發(fā)的重點在于窗口系統(tǒng),其小巧精致并且盡量與Win32兼容。MicroWindows目前開發(fā)的重點在底層的圖形引擎,窗口系統(tǒng)和圖形接口方面功能比較欠缺,與Win32和X Windows窗口系統(tǒng)保持兼容,提供了相對完善的圖形功能。OpenGUI基于一個用匯編實現(xiàn)的x86圖形內(nèi)核,提供了一個高層的C/C++圖形/窗口接口,它的資源消耗小,可移植性差,不支持多進程。
Qt/Embedded是一個多平臺的C++圖形用戶界面應(yīng)用程序框架,其對象容易擴展,可移植性好,支持多個GUI平臺的交互開發(fā)[2,3]?,F(xiàn)在,Qt/Embedded被廣泛地應(yīng)用于各種嵌入式產(chǎn)品和設(shè)備中,從消費電器(如智能手機、機頂盒)到工業(yè)控制設(shè)備(如醫(yī)學(xué)成像設(shè)備、移動信息系統(tǒng)等)。因此本文選擇Qt/Embedded為本系統(tǒng)的GUI。
(1) Qt/Embedded和Qtopia體系結(jié)構(gòu)
Qt/Embedded是Trolltech公司開發(fā)的面向嵌入式系統(tǒng)的Qt版本,與X11版本的Qt在最大程度上接口兼容,采用幀緩存(framebuffer)作為底層圖形接口。Qt/Embedded類庫完全采用C++封裝,并且有著豐富的控件資源以及較好的可移植性,大范圍的Qt /Embedded API可用于多種開發(fā)項目。Qt/Embedded的實現(xiàn)結(jié)構(gòu)如圖(2)所示:
圖(2) Qt/Embedded實現(xiàn)結(jié)構(gòu)
Qt/Embedded的底層圖形引擎基于framebuffer。 framebuffer是一種驅(qū)動程序接口,它將顯示設(shè)備抽象為幀緩沖區(qū)[4]。該驅(qū)動程序的設(shè)備文件一般是/dev/fb0、/dev/fb1等。對用戶而言,它和/dev下的其他設(shè)備沒有什么區(qū)別,用戶可以把framebuffer看成一塊內(nèi)存,既可以從這塊內(nèi)存中讀取數(shù)據(jù),也可以向其中寫入數(shù)據(jù),而寫操作立即反應(yīng)在屏幕上。為運行Qt/Embedded,嵌入式Linux內(nèi)核要支持framebuffer。
Qt/Embedded是Qt的面向嵌入式應(yīng)用的簡化版本,它包括一組完備的GUI類、操作系統(tǒng)封裝、數(shù)據(jù)結(jié)構(gòu)類、功能類和組合類。大部分Qt的應(yīng)用程序可以經(jīng)過簡單的編譯與重設(shè)窗口大小移植到Qt/Embedded。
Qtopia是基于QT/Embedded開發(fā)的一個嵌入式的窗口系統(tǒng)和應(yīng)用程序集,如地址本、圖像瀏覽、Media播放器等,還包括娛樂和配置工具,廣泛用于PDA等掌上設(shè)備。Qtopia平臺由Qtopia 庫(Qt/E,libqpe,libqtopia1,qtopiapim)和Qtopia server/laucher組成。Qtopia server/laucher是控制窗口系統(tǒng)、進程間通信、發(fā)起所有應(yīng)用和其他核心任務(wù)的主要服務(wù)程序。
(2) Qt/Embedded和Qtopia的交叉編譯與運行
整個GUI系統(tǒng)的構(gòu)建需要對Qt/Embedded、Qtopia依次分別編鏈,然后有機地整合在一起。Qt/Embedded為Qtopia提供了底層支持,GUI系統(tǒng)的圖形庫窗口組建都由Qt/Embedded實現(xiàn)。
在構(gòu)建GUI時用于Qt開發(fā)的典型工具如下:
tmake:跨平臺的Makefile生成器。
moc:用于Qt C++擴展的metra-object編譯器。
uic:從XML文件生成代碼的用戶界面編譯器。
designer:用于設(shè)計窗口組建的應(yīng)用程序。
Qtopia的開發(fā)工具包SDK(Software Development Kit)是Qtopia開發(fā)環(huán)境的核心部分,編譯后得到創(chuàng)建應(yīng)用程序所需的軟件包如下:
qvfb(virtual frame buffer):X窗口用來運行和測試Qtopia應(yīng)用程序的系統(tǒng)程序。
qpe(Qtopia executable):用來處理所有的用戶程序界面[2,5]。
由于我們使用的是ARM CPU,因此需要對Qt/Embedded和Qtopia開發(fā)工具包進行交叉編譯。本文使用arm-linux-gcc-3.3.2來建立交叉編譯環(huán)境。為了對Qt/Embedded和Qtopia進行交叉編譯,需要使用如下的源碼樹:
tmake-1.13.tar.gz:用來得到tmake工具。
qt-embedded-2.3.7.tar.gz:Qt的嵌入式版本。
qt-x11-2.3.2.tar.gz:Qt的X11版本。
qtopia-free-1.7.0.tar.gz:官方網(wǎng)站提供的Qtopia免費版。
e2fsprogs-1.38.tar.gz:為了得到qtopia所需的uuid.h和libuuid.so。
假設(shè)將上述源碼樹放在同一目錄下,例如:/root/qtopia,并依次解壓,然后進行編譯,步驟如下:
(1)設(shè)定tmake的環(huán)境變量如下:
- export TMAKEPATH=/root/qtopia/tmake-1.13/lib/qws/linux-arm-g++
此處指定了tmake在生成Makefile時使用arm交叉編譯。
(2)編譯qt-x11,其目的是生成moc、uic、qvfb、designer,并將它們放在qt-embedded\bin目錄下。
(3)配置qt-embedded編譯選項,命令為:
- ./configure -platform linux-arm-g++ -qconfig qpe -qvfb -depths 4,8,16,32.
此處-platform linux-arm-g++表示在arm平臺上進行交叉編譯;-qconfig local表示使用src/tools/qconfig-local.h;-depths 4,8,16,32表示需要qt支持的顯示顏色深度。
④使用make命令編譯qt-embedded,用來生成Qt庫(libqte.so)。
⑤配置并交叉編譯Qtopia,生成應(yīng)用程序以及桌面環(huán)境。
假設(shè)編譯完成后將qt和qtopia相關(guān)的庫及所需文件分別存放于目標(biāo)板文件系統(tǒng)的/opt/qt和/opt/qtopia下,運行Qtopia的方法是:
(1)設(shè)置QTDIR、QPEDIR和鍵盤鼠標(biāo)等環(huán)境變量
- export QTDIR=/opt/qt
- export QPEDIR=/opt/qtopia
- export QWS_KEYBOARD=USB:/dev/input/event1
- export QWS_MOUSE_PROTO=USB:/dev/input/mouse0
(2)開啟qpe,也就是在Linux圖形模式下執(zhí)行/opt/qtopia/bin/qpe &
這樣就可以在顯示終端上看到qtopia桌面環(huán)境了。
4 Qt/Embedded和Qtopia下應(yīng)用程序的實現(xiàn)
(1) Qt/Embedded應(yīng)用程序的實現(xiàn)
Qt是一個創(chuàng)建GUI程序的C++類庫,編寫Qt應(yīng)用程序的主要工作是基于已有的Qt類編寫用戶類。Qt應(yīng)用程序的設(shè)計使用基于工程的方法,并通過.pro文件進行工程管理。實現(xiàn)應(yīng)用程序的第一步是編寫.pro文件,然后使用tmake根據(jù)該文件生成Makefile,最后進行源代碼的編寫。 tmake的語法如下:
- tmake *.pro –o Makefile
.pro的具體內(nèi)容可以參考/qt/examples/下其他應(yīng)用程序的.pro文件。
在本項目的研究中,需要涉及基本的窗口構(gòu)建、應(yīng)用程序的調(diào)用、圖像背景的顯示以及中文顯示,下面對此進行詳細(xì)闡述。
#p#
構(gòu)建主窗口
Qt擁有眾多的窗口部件,如按鈕、菜單、滾動條和應(yīng)用程序窗口等,它們組合起來可以創(chuàng)建各種用戶界面。QWidget 是所有用戶界面對象的基類,窗口部件是QWidget或其子類的實例。
創(chuàng)建主窗口先要在main.cpp函數(shù)中創(chuàng)建QApplication類型的對象。QApplication類管理圖形用戶界面應(yīng)用程序的控制流和主要設(shè)置,它包含主事件循環(huán),在其中來自窗口系統(tǒng)和其它資源的所有事件被處理和調(diào)度,它也處理應(yīng)用程序的初始化和結(jié)束,并提供對話管理。對于任何一個使用Qt圖形用戶界面應(yīng)用程序,都正好存在一個QApplication對象。然后定義主窗口變量,并通過QApplication類型的函數(shù)調(diào)用主窗口變量來啟動主窗口。
創(chuàng)建主窗口部件最常用的方法是基于QWidget或QDialog類創(chuàng)建一個用戶類。QDialog類是對話框窗口的基類,主要用于短期任務(wù)以及和用戶進行簡要通訊的頂級窗口。在本程序中使用QWidget類創(chuàng)建用戶類,并使用戶類通過公有繼承派生于Qwidget類。
在構(gòu)建窗口時需要注意用戶界面的風(fēng)格和布局。Qt提供了Windows、WindowsXP、Motif、MotifPlus、CDE、 Platinum、SGI和Mac的內(nèi)置風(fēng)格。自定義風(fēng)格可以通過繼承QStyle、QCommonStyle或其他QCommenStyle類來完成。應(yīng)用程序的風(fēng)格可以如下設(shè)置:
- QApplication::setStyle(new MyCustomStyle)
在布局上Qt提供了布局管理器來組織父部件區(qū)域中的子部件,Qt內(nèi)建的布局管理器有QHBoxLayout,QVBoxLayout和 QGridLayout,而且布局也可以嵌套在任意層。例如使用QHBoxLayout(按行放置部件)的部件管理器為例在窗口水平放置兩個按鈕B1和 B2的代碼如下:
- QHBoxLayout *hbox = new QHBoxLayout(this);
- Hbox->addWidget(B1);
- Hbox->addWidget(B2);
創(chuàng)建按鈕實現(xiàn)對應(yīng)用程序的調(diào)用
Qt部件與用戶的交互方式不同于其他的GUI工具包,其他的GUI工具包使用回調(diào)函數(shù)創(chuàng)建用戶交互,但是Qt提供了信號/槽(signal/slots) [5]通信機制描述對象間的無縫通訊。槽(slot)是標(biāo)準(zhǔn)的成員函數(shù),它能夠連接到信號,每當(dāng)槽所連接的信號被發(fā)射時,槽(函數(shù))就被執(zhí)行。信號 (signal)是一種特殊類型的函數(shù),都是返回void型,它們被定義為當(dāng)某個事件發(fā)生時就被發(fā)射,之后執(zhí)行所有被連接的槽。當(dāng)定義信號時必須使用QT 的宏SIGNAL(),定義槽時必須使用宏SLOT()。
通過調(diào)用QObject對象的connect函數(shù)可以將某個對象的信號與另一個對象的槽相關(guān)聯(lián),這樣當(dāng)發(fā)射對象發(fā)射信號時,接收對象的槽將被調(diào)用。該函數(shù)定義如下:
- bool QObject::connect(const QObject *sender,const char *signal,const QObject *receiver,
- const char *member)
與這個函數(shù)對應(yīng)的disconnect函數(shù),可以將信號和槽斷開連接。
本文使用了QT庫提供的按鈕clicked()信號,自定義了槽函數(shù)run()來實現(xiàn)對應(yīng)用程序的調(diào)用,并且定義了槽函數(shù)mycall()調(diào)用已經(jīng)使用了特定參數(shù)的run()函數(shù)。
例如當(dāng)一個按鈕B1被點擊時,它就發(fā)送“clicked”信號,通過connect()函數(shù)將信號與槽“mycall”連接起來,調(diào)用/opt/qt/examples/clock/下的應(yīng)用程序“clock”的代碼如下:
- void MyMainWindow::mycall()
- {
- MyMainWindow::run(“(cd /opt/qt/examples/clock; exec ./clock;)”);
- }
- connect(B1,SIGNAL(clicked()),this,SLOT(mycall()));
圖像背景的顯示
為了在Qt中裝載和顯示所支持的圖像格式,需要創(chuàng)建一個QPixmap對象。QPixmap本質(zhì)上是一個“屏幕外的部件(off-screen)”,圖像可以先復(fù)制到一個QPixmap對象上,然后傳送到QWidget。
QWidget部件使用如下的成員函數(shù)來為窗口添加圖像背景:
- Public Members
- const QPixmap* backgroundPixmap () const
- virtual void setBackgroundPixmap ( const QPixmap & )
例如有一幅名為flower.png的圖片,將其設(shè)為背景的代碼如下:
- QPixmap picture(“flower.png”)
- SetbackgroundPixmap(picture)
中文顯示
Qt的中文顯示是Qt國際化的一部分,“國際化”簡稱為i18n,用來提供一個架構(gòu),讓同樣的代碼可以適用于各種語種習(xí)慣和編碼系統(tǒng),程序設(shè)計人員只要利用這個架構(gòu)的機制、準(zhǔn)則編寫應(yīng)用程序,就可以在不新編譯代碼的情況下,支持各種語言。
Qt支持Unicode—國際標(biāo)準(zhǔn)字符集,程序員可以在程序里自由的混用英語、漢語和其他Unicode所支持的語言。為Qt增加一種編碼只需要增加該編碼和Unicode的轉(zhuǎn)化編碼就可以了,Qt支持中文的GBK/Big5編碼。
Qt 支持的字體常用的是ttf和qpf。qpf是Qt/Embedded專用的一種適合嵌入式應(yīng)用的字體,它屬于位圖字體,不可以縮放,而ttf字體可以縮放。默認(rèn)情況下Qt/Embedded在lib/fonts目錄下提供了一種可以顯示中文的字體庫UniFont,但是該字體庫中沒有ttf的字體。為了使用ttf字體顯示中文,本文采取如下的方法:拷貝一種支持unicode編碼的ttf字體到lib/fonts目錄下,例如,windows系統(tǒng)下的宋體simsun.ttf;同時還需要在此目錄的fontdir腳本中添加下面一行:
- simsun simsun.ttf FT n 50 0 su
fontdir腳本用來向系統(tǒng)注冊所支持的字體,它的每一行定義了一種字體的設(shè)置,其格式如下:
<字體名稱><字體文件名><字體渲染類型><是否斜體><尺寸><字體標(biāo)志>[尺寸列表]
在程序設(shè)計中,首先指定編碼方式以支持中文:
- QTextCodec *code=QTextCodec::codecForName("GBK")
接著為部件(例如Mywidget)執(zhí)行 Unicode的轉(zhuǎn)化編碼:
- QString uniStr=code -> toUnicode("要顯示的中文字符")
- Mywidget-> setFont(QFont("simsun",20,QFont::Bold))
- Mywidget-> setText(uniStr)
(2) 向Qtopia移植應(yīng)用程序
Qtopia 是一個基于QT/Embedded開發(fā)的一個嵌入式的桌面環(huán)境和應(yīng)用程序集,可以方便地在Qtopia桌面環(huán)境中添加用戶應(yīng)用程序或者對桌面進行配置。為了添加用戶應(yīng)用程序,需要在Qtopia/apps/Application目錄下建立一個.desktop的桌面文件,該文件指明了桌面文件的圖標(biāo)以及應(yīng)用程序的入口點。應(yīng)該注意的是為了讓新的應(yīng)用程序在Qtopia桌面環(huán)境中運行,應(yīng)用程序必須使用QT提供的圖形庫進行編譯。
下面以移植嵌入式的web瀏覽器konqueror為例,說明添加新的應(yīng)用程序的過程。
下載konqueror源代碼,對其進行交叉編譯。為了支持中文顯示和flash,還需要進行必要的源代碼修改,并且加入相應(yīng)的插件。
將konqueror.png圖標(biāo)文件拷貝到在/opt/Qtopia/pic/下。
將 konqueror可執(zhí)行文件放于/opt/konqueror/下,然后在Qtopia/apps/Application目錄下建立 konqueror.desktop文件,具體內(nèi)容可參考qtopia自帶的.desktop文件。需要注意的是konqueror.desktop的 Exec項應(yīng)指明可執(zhí)行文件的具體位置。例如:Exec=/opt/konqueror/bin/konqueror
導(dǎo)出konqueror的運行環(huán)境變量,就可以直接在桌面上點擊其圖標(biāo)瀏覽網(wǎng)頁了。
小結(jié):基于Qt Embedded和Qtopia GUI設(shè)計的內(nèi)容介紹完了,嵌入式產(chǎn)品的廣泛應(yīng)用帶動了圖形用戶界面(GUI)的迅速發(fā)展,嵌入式系統(tǒng)需要一個高性能、高可靠的GUI的支持?;?strong>Qt Embedded的 Qtopia桌面系統(tǒng)為系統(tǒng)用戶提供了良好的使用和交互環(huán)境。本文系統(tǒng)介紹了基于Qt Embedded開發(fā)應(yīng)用程序的方法以及將現(xiàn)有的應(yīng)用程序移植進 Qtopia的具體過程,為類似的系統(tǒng)開發(fā)供了一個參考。最后希望本文能對你有所幫助!