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