胡澤明,李婧
(1.信息工程大學(xué) 信息系統(tǒng)工程學(xué)院,鄭州 450002;2.河南省水利信息中心)
?
開源GTK向?qū)浇缑婵丶脑O(shè)計(jì)與制作
胡澤明1,李婧2
(1.信息工程大學(xué) 信息系統(tǒng)工程學(xué)院,鄭州 450002;2.河南省水利信息中心)
輕量級(jí)開源GTK平臺(tái)是Linux下開發(fā)圖形界面的應(yīng)用程序主流開發(fā)工具之一,目前廣泛應(yīng)用的GTK2.0版本未提供向?qū)浇缑婵丶疚纳钊敕治鱿驅(qū)浇缑娴牟季植⑻崛∑涔残?,結(jié)合GTK常規(guī)控件設(shè)計(jì)制作了向?qū)浇缑婵丶?,并提供用戶區(qū)布局控件接口供用戶調(diào)用填充內(nèi)容,不僅提供了一致性界面風(fēng)格,且進(jìn)一步提升了GTK向?qū)浇缑娴木帉懶省TO(shè)計(jì)實(shí)例表明,該設(shè)計(jì)方法功能正確、靈活性強(qiáng)、代碼復(fù)用率高,對(duì)基于GTK開發(fā)自定義控件以滿足應(yīng)用需求具有重要的指導(dǎo)意義。
輕量級(jí)GUI;開源GTK;API界面編程;向?qū)浇缑?/p>
GTK+(GIMP Toolkit)是一套源碼以LGPL(Lesser General Public License)許可協(xié)議分發(fā)、跨平臺(tái)的圖形工具包,目前已發(fā)展成為GNU/Linux下開發(fā)圖形界面應(yīng)用程序的主流開發(fā)工具之一[1],有Windows版本和Mac OS版本,能夠支持C/C++、Python等編程語言[2],已從1.0版本發(fā)展到3.0,當(dāng)前應(yīng)用比較多的為2.0版本。GTK+屬于輕量型GUI,編譯后可執(zhí)行文件約幾MB[2],遠(yuǎn)小于MFC或QT對(duì)計(jì)算機(jī)資源的需求,目前在Linux平臺(tái)得到了廣泛應(yīng)用,如GNOME、XFCE等桌面環(huán)境和大部分窗口管理器都基于GTK+。
輕量級(jí)GTK具有的開源性、設(shè)計(jì)靈活性和可擴(kuò)展性,以及豐富GUI構(gòu)件集[3],為用戶基于GTK開發(fā)提供了堅(jiān)實(shí)基礎(chǔ),但GTK屬于APIs函數(shù)式編程模型,不支持直觀的“所見即所得”可視化界面編程。在一些基于GTK開發(fā)的軟件系統(tǒng)中,涉及到類似Windows平臺(tái)向?qū)浇缑娴拈_發(fā)需求,可以實(shí)現(xiàn)簡單直觀的軟件部署或系列參數(shù)設(shè)置等。但分析GTK2.0,其未提供向?qū)浇缑婵丶?,從而加大了開發(fā)難度。為此深入分析向?qū)浇缑娴牟季?,并提取其共性特性后,基于GTK控件集設(shè)計(jì)并實(shí)現(xiàn)了向?qū)浇缑婵丶?,且預(yù)留用戶區(qū)自定制布局控件接口,供用戶擴(kuò)展、定制具體界面內(nèi)容。應(yīng)用實(shí)例表明,所設(shè)計(jì)的向?qū)浇缑婵丶?,功能正確、靈活性強(qiáng)、風(fēng)格一致性好、代碼復(fù)用率高;同時(shí)該設(shè)計(jì)方法對(duì)基于GTK開發(fā)自定義控件、擴(kuò)展功能特性、實(shí)現(xiàn)軟件系統(tǒng)具有較強(qiáng)的借鑒意義。
1.1 GTK體系結(jié)構(gòu)
GTK應(yīng)用程序由基于GTK+提供的接口函數(shù)集APIs來編寫,包括Glib庫、GObject庫GDK庫等依賴庫,這些庫分別實(shí)現(xiàn)不同的功能,如圖1所示。
圖1 GTK+體系結(jié)構(gòu)
在圖1中,主要庫及功能包括:Glib庫提供底層的數(shù)據(jù)結(jié)構(gòu)、類型、多線程支持、事件循環(huán)和動(dòng)態(tài)加載等;GObject庫用C編程實(shí)現(xiàn)的面向?qū)ο笙到y(tǒng);Pango庫即語言庫,支持文本的渲染和布局,實(shí)現(xiàn)本地化和國際化;GDK庫處理Xlib上的底層圖形渲染,如“圖形實(shí)現(xiàn)”和“窗口實(shí)現(xiàn)”;GdkPixbuf庫幫助處理GTK+程序中的圖像,用于加載圖像和維護(hù)圖像緩存;Xlib庫提供位于操作系統(tǒng)上的底層繪圖函數(shù);GModule庫支持動(dòng)態(tài)加載插件。
1.2 GTK事件響應(yīng)機(jī)制
GTK+是一個(gè)依賴于事件、信號(hào)、回調(diào)機(jī)制的軟件系統(tǒng)。一個(gè)事件是由X窗口發(fā)出的消息,當(dāng)用戶執(zhí)行一些動(dòng)作,如移動(dòng)鼠標(biāo)、敲擊鍵盤時(shí),對(duì)應(yīng)事件就被發(fā)送到GTK程序,被Glib的信號(hào)系統(tǒng)所解釋。當(dāng)該事件到達(dá)GTK構(gòu)件(GtkWidget)時(shí),信號(hào)就發(fā)生了,此時(shí)可告訴GTK+運(yùn)行1個(gè)函數(shù),即所謂的回調(diào)函數(shù)。
在GTK2.0中,事件響應(yīng)實(shí)現(xiàn)對(duì)應(yīng)信號(hào)連接函數(shù)g_signal_connect()和回調(diào)函數(shù)callback_func()。
g_signal_connect()函數(shù)原型:
gulong g_signal_connect(gpointer object, const gchar* name, GCallback func, gpointer func_data);
//object指需要監(jiān)聽信號(hào)的控件
//name為需要監(jiān)聽的信號(hào)名稱
//func為發(fā)生信號(hào)后的回調(diào)函數(shù)
//func_data是傳遞給信號(hào)處理函數(shù)func的參數(shù),可為NULL
callback_func ()函數(shù)原型:
當(dāng)GTK構(gòu)件上信號(hào)發(fā)出時(shí),在g_signal_connect()中指定的回調(diào)函數(shù)被調(diào)用?;卣{(diào)函數(shù)有如下的形式,它是被程序員命名的。
void callback_func(GtkWidget *widget, gpointer func_data);
//widget指向接收信號(hào)的控件
//func_data是傳遞的消息,對(duì)應(yīng)g_signal_connect()中第4個(gè)參數(shù),需強(qiáng)制類型轉(zhuǎn)換
信號(hào)連接及回調(diào)函數(shù)舉例:
//針對(duì)退出事件"delete_event",注冊(cè)主窗口退出函數(shù):
g_signal_connect(G_OBJECT(mainwin),"delete_event",G_CALLBACK(gtk_quit),NULL);
//主窗口退出函數(shù)回調(diào)函數(shù)
voidgtk_quit(G_OBJECT(mainwin), NULL);
1.3 GTK界面構(gòu)件
GTK+2.0采用基于面向?qū)ο蟮拈_發(fā)模式,除了提供基本的隊(duì)列、鏈表等底層構(gòu)件外,類似于Windows MFC,還提供豐富的GUI界面構(gòu)件,用于人機(jī)交互。這類構(gòu)件集[3]包括:窗體類的窗口(GtkWindow)、對(duì)話框(GtkDialog)、筆記本構(gòu)件(GtkNotebook)等,可編輯類的編輯框(GtkEntry)、組合框(GtkCombox)等,人機(jī)交互類的菜單(GtkMenu)、按鈕(GtkButton)、工具欄(GtkToolbar)等;控制類的定時(shí)器、進(jìn)度條等;能容納多個(gè)控件的盒狀容器(GtkBox)、格狀容器(GtkTable)、按鈕盒(GtkButtonBox)、分隔面板(GtkPanel)、固定布局(GtkFixed)等,用于構(gòu)件的排列布局。
GTK+2.0提供一種用最短的代碼來編寫窗口和控件的方法,以及靈活易用的信號(hào)/回調(diào)函數(shù)機(jī)制。使用GTK編寫控件代碼時(shí)要注意代碼書寫順序:先定義窗口變量,再創(chuàng)建窗口,然后加回調(diào)函數(shù),最后顯示窗口。以窗口構(gòu)件為例,其相關(guān)代碼段如下:
void gtk_usr_wintest(void){
GtkWidget *window;//定義窗口變量
window=gtk_window_new(GTK_WINDOW_TOPLEVEL); //創(chuàng)建窗口
g_signal_connect(G_OBJECT(window),"delete event",G_CALLBACK(gtk_main_quit), NULL);//加回調(diào)函數(shù)
gtk_widget_show(window); //顯示窗口
}
2.1 向?qū)浇缑娌季峙c分析
軟件界面設(shè)計(jì)中的“向?qū)浇缑妗边@個(gè)術(shù)語來自英語中的“Wizard”一詞。在實(shí)際使用中,這種交互方式就像一個(gè)向?qū)б粯?,一步步地引領(lǐng)用戶向前。在每一步中,它會(huì)詢問用戶一些簡單的問題,并根據(jù)輸入信息幫助用戶完成一個(gè)復(fù)雜的任務(wù)。分析現(xiàn)有資料[4],設(shè)計(jì)向?qū)浇缑娴囊恍┰瓌t如下:
① 需要時(shí)刻展示整個(gè)向?qū)н^程及當(dāng)前位置,一般處理方式為在每個(gè)步驟頁面的固定位置顯示一個(gè)所有步驟名稱的列表,并且以一種醒目的方式顯示當(dāng)前所處的步驟;
② 每個(gè)步驟上信息量的設(shè)置要合理,一般處理方式要確保每個(gè)步驟中內(nèi)容的內(nèi)聚性以及不同步驟之間內(nèi)容的松耦合性;
③ 要保證步驟的唯一性,即用戶只要在向?qū)Ы缑嫔贤瓿伤胁僮?,就能?shí)現(xiàn)最終的任務(wù),而不需要再啟動(dòng)別的進(jìn)程,或者執(zhí)行額外的命令;
④ 易避免誤操作性,即要求盡可能做到每一步驟都可回退,不可回退的要進(jìn)行提示,界面中條件激活按鈕當(dāng)條件滿足時(shí)才可激活,否則處于變灰不可用狀態(tài)。
基于上述原則,向?qū)浇缑娌季秩鐖D2所示。
圖2 向?qū)浇缑娌季謭D
其分析內(nèi)容如下:
① 底圖:一般為對(duì)話框窗體,尺寸、風(fēng)格等外觀允許用戶設(shè)置;
② 標(biāo)題區(qū):一般位于頂部,為窗體的標(biāo)題,首次設(shè)置后,在后續(xù)步驟中,基本不變;
③ 向?qū)Р襟E區(qū):一般位于左側(cè)欄,安裝過程始終不變且一直存在,同時(shí)需要醒目指示用戶當(dāng)前所處的安裝步驟;
④ 按鈕操作區(qū):一般位于底部,包含【上一步】、【下一步】、【保存】等操作按鈕,支持用戶回退或前進(jìn),推動(dòng)安裝步驟進(jìn)行;
⑤ 用戶定義區(qū):一般位于居中右側(cè)欄,對(duì)應(yīng)著用戶定制的向?qū)浇缑鎯?nèi)容,APIs編程模式中需要提供布局參數(shù),支持用戶按需編寫代碼,繪制GUI界面元素。
2.2 向?qū)浇缑婵丶脑O(shè)計(jì)
圍繞向?qū)浇缑娌季值姆治?,結(jié)合GTK+2.0構(gòu)件集,參考基于GTK的自定義控件實(shí)現(xiàn)方法[5-6],可設(shè)計(jì)通用的向?qū)浇缑婺0?,其中用GtkWindow控件創(chuàng)建窗體、水平(GtkHBox)或垂直盒狀容器(GtkVBox)實(shí)現(xiàn)界面布局,并為程序開發(fā)者提供用戶區(qū)布局容器句柄,按鈕盒(GtkButtonBox)創(chuàng)建底部按鈕,以及分欄列表構(gòu)件(GtkCList)展示向?qū)Р襟E等,并通過上述界面控件操作函數(shù)集APIs實(shí)現(xiàn)對(duì)屬性參數(shù)的調(diào)整等。
基于GTK設(shè)計(jì)實(shí)現(xiàn)向?qū)浇缑婵丶r(shí),為方便用戶編程、增強(qiáng)控制靈活性,需要存儲(chǔ)部分關(guān)鍵參數(shù),定義關(guān)鍵結(jié)構(gòu)體如下:
typedef struct{ //定義向?qū)浇缑娼Y(jié)構(gòu)體
GtkWidget *pWin; //向?qū)Т绑w句柄
GtkWidget *pClientVbox; //用戶定義區(qū)垂直容器盒, //提供給用戶進(jìn)行界面布局
GtkWidget *pBtnHbox; //按鈕區(qū)水平容器盒,提供 //給用戶設(shè)置安裝進(jìn)行按鈕
GtkWidget *pBtn[]; //存儲(chǔ)按鈕句柄,用戶設(shè)置回 //調(diào)函數(shù),設(shè)置按鈕狀態(tài)等
gint nBtnNum; //按鈕個(gè)數(shù)
GtkWidget *pStepBox; //安裝步驟容器
GtkWidget *pStepClist; //安裝步驟列表
gint nStepNum; //安裝步驟數(shù)
}stGtkWizard;
GTK向?qū)浇缑娌季植糠痔匦约敖涌诤瘮?shù)如下:
① 窗體:作為向?qū)浇缑娴幕敬翱?,?chuàng)建后需返回窗體控件句柄,放入stGtkWizard結(jié)構(gòu)體中。
stGtkWizard* GtkWizard_CreateWin( gint w, gint h);
//創(chuàng)建窗體
② 標(biāo)題區(qū):首次設(shè)置后不再修改,無返回值。GtkWidget*GtkWizard_GetWin(stGtkWizard*pstGtkWizard);
//獲取窗體句柄voidGtkWizard_SetTitle(GtkWidget*WizardWin, gchar*title);
//設(shè)置窗體標(biāo)題
③ 向?qū)Р襟E區(qū):初始設(shè)置后不再改變,提示用戶當(dāng)前所處的步驟。
GtkWidget* GtkWizard_GetStepBox (stGtkWizard* pstGtkWizard); //獲取安裝進(jìn)度盒容器句柄
GtkWidget* GtkWizard_GetStepClist (stGtkWizard* pstGtkWizard); //獲取安裝步驟列表句柄
void GtkWizard_CreateSteps(GtkWidget*pBox, GtkWidget* pClist, gchar *title, gchar *steps[] );
//設(shè)置安裝步驟內(nèi)容
void GtkWizard_SetCurSteps(GtkWidget*pClist,gint nstep);
//設(shè)置安裝步驟高亮顯示
④ 按鈕區(qū):推動(dòng)向?qū)Р襟E進(jìn)行,對(duì)應(yīng)按鈕標(biāo)題、按鈕狀態(tài)允許用戶調(diào)整設(shè)置,以及設(shè)置響應(yīng)函數(shù)。GtkWidget*GtkWizard_GetBtnHbox (stGtkWizard*pstGtkWizard);
//獲取按鈕句柄
void GtkWizard_SetBtn(GtkWidget*pBtn, gchar *title, GCallback btn_cb, gint nstate);
//設(shè)置按鈕標(biāo)題、回調(diào)函數(shù)及狀態(tài)
⑤ 用戶定義區(qū):GTK編程時(shí)提供布局參數(shù)句柄,支持用戶定制內(nèi)容。
GtkWidget* GtkWizard_GetClientVbox (stGtkWizard* pstGtkWizard);
//獲取用戶區(qū)盒狀容器句柄
2.3 應(yīng)用實(shí)例
用GTK+2.0 開發(fā)應(yīng)用系統(tǒng),無論是Windows平臺(tái)Visual Studio集成開發(fā)環(huán)境、Linux平臺(tái)Eclipse集成開發(fā)環(huán)境,還是Linux平臺(tái)GCC命令行Make環(huán)境,都需要首先完成正確的編程環(huán)境設(shè)置,主要包括兩個(gè)內(nèi)容:其一為GTK依賴庫和頭文件的包含,其二為庫和頭文件路徑以及環(huán)境變量的設(shè)置等。
在Ubuntu 10.04.2 Linux環(huán)境中,基于make文件進(jìn)行編譯設(shè)置[1],配置方式較為簡單,直接在makefile文件頭部設(shè)置連接標(biāo)志LIBFLAG = `pkg-config gtk+-2.0 --cflags --libs` 即可。
基于第2節(jié)所設(shè)計(jì)并實(shí)現(xiàn)的向?qū)浇缑鍭PIs接口,結(jié)合具體應(yīng)用需求,在不同向?qū)Р襟E界面中用戶區(qū)添加一些GTK控件進(jìn)行多次測試,功能正確,運(yùn)行穩(wěn)定。向?qū)浇缑鎸?shí)現(xiàn)實(shí)例部分截圖如圖3所示。
圖3 基于向?qū)浇缑婵丶膽?yīng)用實(shí)例圖(節(jié)選)
通過對(duì)比上文所設(shè)計(jì)實(shí)現(xiàn)的GTK向?qū)浇缑婢幊谭椒ㄒ约皞鹘y(tǒng)GTK界面編程實(shí)現(xiàn)方法,其雖然初始設(shè)計(jì)實(shí)現(xiàn)向?qū)浇缑婵丶y度高,代碼調(diào)試工程量大;但是后期應(yīng)用時(shí),代碼復(fù)用率高,界面風(fēng)格一致性好,修改維護(hù)簡單,且可擴(kuò)展性好。
[1] 宋國偉.GTK+2.0編程范例[M].北京:清華大學(xué)出版社,2002.
[2] What is GTK+, and how can I use it? [EB/OL].[2016-07].http://www.gtk.org.
[3] GTK+ reference manual[EB/OL].[2016-07].http://doc.gnu-darwin.org/gtk20.
[4] 如何設(shè)計(jì)一個(gè)優(yōu)秀的向?qū)浇缑鎇EB/OL].[2016-07].http://www.360doc.com/content/16/0601/10/16915_564127800.shtml.
[5] 李國玲.Linux下GTK+自定義控件的設(shè)計(jì)和使用[J].科技與創(chuàng)新,2015(15):115-116.
[6] 葉超.GNU/Linux環(huán)境下基于GTK+的圖形用戶界面開發(fā)[D].長春:中科院長春光學(xué)精密機(jī)械與物理所,2007.
胡澤明(副教授),主要研究方向?yàn)榭缙脚_(tái)信息處理技術(shù)等。
Design and Realization of Wizard-interface Component Based on Open-source GTK
Hu Zeming1,Li Jing2
(1.Institute of Information System Engineering,Information Engineering University,Zhengzhou 450002,China;
2.Water Information Center of Henan Province)
GTK with the characteristics of open-source and light-weight is becoming the one of main graphic development platforms in Linux,and the version 2 cannot provide wizard-interface component for the users.In the paper,the layout of wizard-interface is analyzed,then the wizard-interface components by the GTK common components are designed.At the same time,an interface is reserved for the users to configure contents by themselves,thus the uniform wizard-interface style is provided,and the efficiency of coding is promoted highly.At last,an example shows that the method has a specification of high code-reusing and flexibility,which is very helpful to develop self-configured component for the users to satisfy the special application demands.
light-weight GUI;open-source GTK;API interface coding;wizard-interface
TP311
A
?士然
2016-07-20)