2003 年 5 月 10 日
FLTK(Fast Light Tool Kit 發(fā)音為fulltick) 是一種使用C++開發(fā)的GUI工具包,它可以應(yīng)用于Unix,Linux,MS-Windows95/98/NT/2000和MacOS操作系統(tǒng)平臺,相對于其它的許多圖形接口開發(fā)工具包(如MFC、GTK、QT等),它具有體積很小、速度比較快,且有著更好的移植性。
FLTK(Fast Light Tool Kit 發(fā)音為fulltick) 是一種使用C++開發(fā)的GUI工具包,它可以應(yīng)用于Unix,Linux,MS-Windows95/98/NT/2000和MacOS操作系統(tǒng)平臺,相對于其它的許多圖形接口開發(fā)工具包(如MFC、GTK、QT等),它具有體積很小、速度比較快,且有著更好的移植性。本文就FLTK編程的一些基本方法進(jìn)行介紹。
FLTK功能簡介
1. 提供豐富的跨平臺的GUI構(gòu)件(Widget)。有按鈕,菜單,窗口等,近六十個。
2. 支持OpenGL,提供Fl_GL_Window,支持OpenGL相關(guān)的操作。
3. 提供界面設(shè)計工具FLUID,非常方便進(jìn)行界面的設(shè)計。
4. 良好的跨平臺移植性。
5. 支持多種C++編譯器,Gcc,BC,VC等等。
6. 靈活性。FLTK本身可以定制,以滿足不同的需要。這使得FLTK在嵌入式開發(fā)上有著極大的競爭力,這正是我要推薦使用FLTK的原因。
本文就FLTK編程的一些基本方法進(jìn)行介紹。
安裝
安裝FLTK很簡單,我們只需要下載它的源文件,解壓縮到目錄下,在Linux下我們只需要輸入make,編譯完成然后make install就頭文件安裝到/usr/include/FL目錄下。庫文件就在/usr/lib下,也可以自己編譯之后把這些文件復(fù)制到這些目錄,或者不需要復(fù)制,只在編譯連接的時候指定路徑。
在window下可以使用VC,BC打開相應(yīng)目錄下的工程文件編譯即可。
FLTK構(gòu)件簡介
FLTK作為GUI開發(fā)包,包含了常用的圖形用戶接口需要的一些構(gòu)件,視覺表現(xiàn)非常豐富,如下兩圖所示:
常用按鈕構(gòu)件
按鈕名稱 |
頭文件 |
按鈕名稱 |
頭文件 |
Fl_Button |
Fl_Button.H |
Fl_Check_Button |
Fl_Check_Button.H |
Fl_Light_Button |
Fl_Light_Button.H |
Fl_Repeat_Button |
Fl_Repeat_Button.H |
Fl_Return_Button |
Fl_Return_Button.H |
Fl_Round_Button |
Fl_Round_Button.H |
對于具有Fl_Check_Button、Fl_Loght_Button和Fl_Round_Button當(dāng)狀態(tài)為off時value() =0 ,On時value()返回1。
處理按鈕時間可以使用回調(diào)(callback)函數(shù),參見后面的事件處理。
文本處理構(gòu)件
構(gòu)件名稱 |
頭文件 |
構(gòu)件名稱 |
頭文件 |
Fl_Input |
Fl_Input.H |
Fl_Output |
Fl_Output.H |
Fl_Multiline_Input |
Fl_Multiline_Input.H |
Fl_Multiline_output |
Fl_Multiline_output.H |
設(shè)置和取得文本內(nèi)容使用value();
如:
(new Fl_Input(x,y,width,height,"Label"))->value("Hello World!");
|
其他構(gòu)件
參見FLTK.org的 文檔說明。
這些構(gòu)件是使用C++開發(fā)的,具有完善的繼承關(guān)系,下面是構(gòu)件繼承關(guān)系圖
構(gòu)件使用例子-HelloWorld
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Box.H>
int main (int argc, char *argv[])
{
Fl_Window *window;
Fl_Box *box;
window = new Fl_Window (300, 180);
window-> label("HelloWorld!"); //添加window的標(biāo)題
box = new Fl_Box (20, 40, 260, 100, "Hello World!");
box->box (FL_UP_BOX);
box->labelsize (36);
box->labelfont (FL_BOLD+FL_ITALIC); //設(shè)置字體
box->labeltype (FL_SHADOW_LABEL); //設(shè)置label的類型
/***************************************************************
進(jìn)入FLTK的事件循環(huán)處理過程
***************************************************************/
window->end ();
window->show (argc, argv);
return Fl::run();
}
|
在window下程序編譯運(yùn)行后如圖所示:[使用VC6編譯優(yōu)化后大小為116K]
Linux下圖片[編譯未優(yōu)化大小358K]
FLTK事件處理
對于一般構(gòu)件的如按鈕,菜單等常用事件的處理一般可以使用回調(diào)函數(shù)實(shí)現(xiàn),回調(diào)函數(shù)的原型是:
void XXX_callback( Fl_Widget *w,void *data )
{
//添加自己處理的內(nèi)容
}
使用F1_Widget->callback( XXX_callback,data) 注冊回調(diào)函數(shù)
/***************************************************************
按鈕事件例子
***************************************************************/
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_ask.H>
void Btn01_cb(Fl_Widget *w,void *data)
{
((Fl_Button *)w)->label((char *)data);
fl_alert("Hello");
}
int main(int argc, char **argv)
{
char *buff ="Hello";
Fl_Window* w = new Fl_Window(272, 144);
Fl_Button* Btn01 = new Fl_Button(85, 50, 105, 25, "&Test callback");
Btn01->shortcut(FL_ALT+'t'); //定義按鈕的快捷鍵
Btn01->callback((Fl_Callback*)Btn01_cb,buff); //調(diào)用處理函數(shù) buff作為參數(shù)
w->end();
w->show(argc, argv);
return Fl::run();
}
|
編譯運(yùn)行程序,鼠標(biāo)點(diǎn)擊按鈕,按鈕標(biāo)簽會發(fā)生改變,并且會彈出提示框。
通常的callback是當(dāng)構(gòu)件的value改變時調(diào)用,可以使用when()改變?yōu)槠渌录l(fā)生調(diào)用回調(diào)函數(shù),主要事件有以下事件
事件 |
說明 |
FL_WHEN_NERVER |
從不調(diào)用回調(diào)函數(shù) |
FL_WHEN_CHANGED |
當(dāng)構(gòu)件值改變時調(diào)用 |
FL_WHEN_RELEASE |
當(dāng)釋放按鍵或者鼠標(biāo)并且構(gòu)件值改變 |
FL_WHEN_RELEASE_ALWAYS |
當(dāng)釋放按鍵或者鼠標(biāo),即使構(gòu)件值沒有改變 |
FL_WHEN_ENTER_KEY |
按下Enter鍵并且構(gòu)件值改變 |
FL_WHEN_ENTER_KEY_ALWAYS |
按下Enter鍵,即使構(gòu)件值沒有改變 |
通過使用F1_Widget->when(FL_WHEN_XXXX)來改變回調(diào)事件。
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_ask.H>
void Btn01_cb(Fl_Widget *w, void *data)
{
fl_alert("Hello");
}
int main(int argc, char **argv)
{
char *buff = "Hello";
Fl_Window* w = new Fl_Window(272, 144);
Fl_Button* Btn01 = new Fl_Button(85, 50, 105, 25, "&Test callback");
Btn01->shortcut(FL_ALT + 't');
Btn01->callback((Fl_Callback*) Btn01_cb, buff);
Btn01->when(FL_WHEN_RELEASE_ALWAYS);
w->end();
w->show(argc, argv);
return Fl::run();
}
|
編譯運(yùn)行程序,在按鈕上按下鼠標(biāo)左鍵,移動到按鈕外,松開鼠標(biāo)按鍵,仍然會彈出對話框,對比上面的兩程序,看看有什么不同。
FLTK消息處理
在FLTK中是通過Fl_Widegt::handle(),虛擬函數(shù)來處理系統(tǒng)的消息。我們可以查看Fltk的源代碼來分析系統(tǒng)是怎樣處理一些系統(tǒng)消息的,如按鈕的消息處理
/*******************************************************
Fl_Button中處理消息的代碼,省略了具體的處理代碼
*******************************************************/
int Fl_Button::handle(int event) {
switch (event)
{
case FL_ENTER:
case FL_LEAVE: return 1;
case FL_PUSH: ……
case FL_DRAG: ……
case FL_RELEASE: ……
case FL_SHORTCUT: ……
case FL_FOCUS : ……
case FL_UNFOCUS : ……
case FL_KEYBOARD : ……
default:
return 0;
}
}
|
可以看出了,系統(tǒng)的一些消息,都是在構(gòu)件的handle()中進(jìn)行處理的。
系統(tǒng)的主要消息有以下
鼠標(biāo)事件消息 |
焦點(diǎn)事件消息 |
FL_PUSH |
FL_ENTER |
FL_DRAG |
FL_LEAVE |
FL_RELEASE |
FL_FOCUS |
FL_MOVE |
FL_UNFOCUS |
鍵盤事件消息 |
剪貼板事件消息 |
FL_KEYBOARD |
FL_PASTE |
FL_SHORTCUT |
FL_SELECTIONCLEAR |
|
構(gòu)件事件消息 |
FL_DEACTIVATE |
FL_ACTIVE |
FL_HIDE |
FL_SHOW |
通過重載handle函數(shù)我們可擴(kuò)充標(biāo)準(zhǔn)構(gòu)件,下面是一個鼠標(biāo)移動到上面就改變顏色的按鈕的實(shí)現(xiàn)源代碼。
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Button.H>
#include <FL/fl_ask.H>
class EnterButton : public Fl_Button
{
int handle(int e)
{ switch (e)
{
case FL_ENTER:
color(FL_GREEN);
labelsize(18); redraw();
return 1;
case FL_LEAVE:
color(FL_GRAY);
labelsize(18); redraw();
return 1;
default:
return Fl_Button::handle(e);
}
}
public: EnterButton(int x, int y, int w, int h, const char *l )
: Fl_Button(x,y,w,h,l) { }
};
static void cb(Fl_Widget* s, void *data)
{
fl_alert( "Hello World!" );
}
int main(int argc, char **argv)
{
Fl_Window* w = new Fl_Window(130, 50);
EnterButton *eBtn = new EnterButton(25,50,120,25,"HelloWorld");
eBtn->callback((Fl_Callback*)cb);
w->end();
w->show(argc, argv);
return Fl::run();
}
|
運(yùn)行顯示效果如圖:
Linux下演示[截屏?xí)r鼠標(biāo)沒有取到]
FLUID簡介
FLUID (FLTK UserInteface Designer)是FLTK進(jìn)行程序界面設(shè)計的有力工具,如同GTK界面開發(fā)工具Glade一樣。
它包含在FLTK源代碼中,需要自己編譯成可執(zhí)行文件。在Window平臺可以使用VC/BC編譯成可執(zhí)行文件。啟動和設(shè)計時界面如圖所示:
Fluid非常容易使用,首先是新建,輸入文件名,后點(diǎn)Bin 窗口的Function 圖標(biāo),建立main主函數(shù)[清空name就可以],然后可以選擇window 圖標(biāo),建立窗口,然后拖放其他構(gòu)件,可以在雙擊構(gòu)件設(shè)置構(gòu)件的屬性【如下圖】,在GUI屬性頁中設(shè)置標(biāo)簽和快捷鍵,位置大小,圖片,提示,對齊方式等,在style中設(shè)置它的顯示風(fēng)格等,在C++中設(shè)置名字,書寫它的回調(diào)函數(shù)等。
設(shè)計好界面后,我們可以把這些轉(zhuǎn)換為C++源代碼,選菜單File中的write Code即可,使用編輯器可以打開與工程同名的源文件和頭文件,怎么做,不再贅述。
OpenGL編程
在FLTK中很容易使用OpenGL進(jìn)行圖形編程的,我們只需要使用它的Fl_Gl_Window構(gòu)件,重新定義一個派生于Fl_Gl_Window的類,重載draw()和handle()就可以。所需要的代碼和步驟如下:
包含以下頭文件
#include <FL/Fl.H>
#include <FL/gl.h>
#include <FL/Fl_Gl_Window.H>
|
定義一個子類,如下代碼所示
class MYGLWindow : public Fl_Gl_Window
{
void draw(); //作圖操作
void handle( int ); //消息事件處理
public :
MYGLWindow(int x,int y,int w,int h,const char *L) : Fl_Gl_Window(x,y,w,h,L){};
};
|
實(shí)現(xiàn)draw()事件
void MYGLWindow::draw() //作圖
{
if ( ! valid() )
{
//設(shè)置viewport窗口大小等等 例如
/**********************************************
valid(1);
glLoadIdentity();
glViewport(0,0,w(),h());
***********************************************/
}
//添加使用OPENGL作圖操作
/* ……..*/
};
|
事件處理實(shí)現(xiàn)
void MYGLWindow::handle( int event) //事件處理
{ switch (event)
{ case FL_PUSH : //操作等
return 1;
case …….
}
}
|
注意
1. 編譯時需要包含openGL32的庫文件,名字在不同的平臺名字稍微不同。
2. 使用<FL/gl.h>代替<GL/gl.h>頭文件,不要使用后者的頭文件。
例子程序比較長,附在參考中。運(yùn)行顯示,彈出菜單后如圖所示:
VC中使用FLTK
在Vc中無法直接使用FLTK,需要下載FLTK的源文件編譯之后再進(jìn)行一些簡單的設(shè)置,設(shè)置步驟如下:
1. 打開Project->Settings->Link, 添加以下庫文件: wsock32.lib opengl32.lib glu32.lib fltk.lib fltkgl.lib [fltk.lib fltkgl.lib 需要自己編譯FLTK源文件生成,直接打開源文件下的visualc目錄下的工程文件就可以編譯]
2. 在Project->Settings->Link的PROJECT OPTIONS中 添加 /nodefaultlib:"LIBCD",如果你要生成release版本的那么是 /nodefaultlib:"LIBC"
3. 在Tools->Options->Directories, 選擇 include files 添加路徑如 C:\Program Files\fltk [對照自己的修改]
4. 在Tools->Options->Directories, 選擇 library files 設(shè)定為如下所示 C:\Program Files\fltk\lib [對照自己的修改]
5. Project->Settings->C/C++ 中的category 選擇 C++ Language
6. 在Project->Settings->C/C++,的PROJECT OPTIONS添加: /I "c:\program files\fltk" [對照修改],此處不修改也可以編譯
KDevelop中使用FLTK
作為跨平臺的一種輕量級的GUI Tools,在Linux下得到更為廣泛的使用,所以我們使用Linux下的最常用的Kdevelop也能很方便使用它。下面簡述需要注意的配置步驟:
1. 我們建立C++工程后,需要修改的配置都在菜單[項目]-->[選項]'[連接器選項]中修改
2. 在[庫]中選定 X11和Xext,根據(jù)自己的需要還需要選定 math等庫
3. 在[附加庫]那里輸入 -L/usr/X11R6/lib -lfltk
4. 如果開發(fā)OpenGL應(yīng)用需要 在附加庫中輸入 -lfltk_gl -lglut 指定連接庫。
提示:因為我使用的Linux為RedHat 8,為選擇中文環(huán)境,所以配置說明也是中文,英文版本可能有所不同,對照修改即可.
參考資料
1. 想了解更多的FLTK的知識和下載FLTK源代碼等可以到 www. 網(wǎng)站。 FLTK的編程手冊你想了解FLTK構(gòu)件的事件方法等都在里面。OpenGL
2. 還是參考一下 www.上的資料吧,有文檔說明還有教學(xué)和源代碼。
關(guān)于作者
|
|
|
左錦,就職南沙資訊科技園,喜愛 Linux,Java 還有藍(lán)天白云青山綠水。通過 zuo170@163.com和他聯(lián)系。
|
|