分享
 
 
 

利用GNOME Libraries来使应用程序的撰写更加容易

王朝other·作者佚名  2006-11-24
窄屏简体版  字體: |||超大  

让我们经由回答读者可能有的一些疑问来当作本文的开始...

[Q] GNOME 是什麽?

GNOME 是∶

UNIX 下图形操作界面环境

收集许多有用、小型的应用与工具程序

设计给应用程序的函式库集

[Q] 为何要使用 GNOME libraries ?

为什麽不乾脆直接使用一套 GUI 工具, 例如∶ GTK+ 、 Motif 或是 Qt 呢? 这些工具都有它们的优点,不过我相信使用 Gnome 的优点远远超过 单独使用那些 GUI 工具。用 Gnome ,你可以省下很多时间, 因为许多程序码都已经写好了,许\多 widgets 也已经建立好了。 这些 widgets 会在全部使用 Gnome 的程序里有大略一致的外观和 格调,此外,程序码的共享,可以让许多应用程序省下记忆体使用 量,因为,这些程序码是共享函式库 (share library) 的一部份 而不是每个应用程序都重覆地载入它们。 其实, Gnome 最大的优势在於 Gnome libraries 可以让你专注在你 的应用程序所要达成的功能,而不必浪费时间在撰写使用者界面 与程序除错上。

原序照录

Developer and GNOME project member George Lebl gives both an overview of the power of the GNOME libraries and an introduction to the techniques of application building. Not only are the libraries used to build GUIs, they also serve as an instrumental part of many other projects. George illustrates GNOME development techniques with a simple Hello World application, taking you through it one step at a time.

开始撰写 GNOME 应用程序

所以你确信要用 GNOME ?好的,我们从最基本的开始, GNOME 应用程序 用了很多 libraries ,这些 libraries 是有阶层关系的,而 GNOME libraries 则在最顶端, GNOME libraries 包括有在线说明功能、类别及特制的 widgets ( 例如 GnomeCanvas ,一个快速、自由订制、高阶的绘图 widgets ) ,并提供应用程序的 framework ( 基础工作 )。

在图上第二高阶层的是 GTK ,属於 GTK+ libraries 的一部份。这个 libraries 提供了基本的 toolkit 和 widgets ( 例如∶按钮、标签和输入盒 (entry boxes) ) 来建立图形操作界面应用。大部份的图形操作界面程序码 是直接经由 GTK , GTK 也提供了精巧的物件系统供 GNOME libraries 使用。

下一层则是 GDK ,是环绕最底层 X library 的薄薄包装,只有在你有特别 的绘图需求或设定视窗上特殊属性时才需要。

在最底层的 GLib 是 C 语言的工具函式库,在许多 container class ( 容器类别 ) 像是 linked lists , resizable array , variable-length strings , hashes , caches , an event loop 和其他有用的类别上提供可携性 (portability) 与工具函式。

不要认为 C 语言是你在发展 GNOME 应用程序时唯一可用的语言, 事实上,因为 GTK+ 和 GNOME 都是以 C 语言写的,它很容易被 其他语言套用,例如 Objective C, C++, Perl, Guile, Python, 和 Eiffel

GNOME & GTK+ 层次

GNOME libraries 区分成三个基本部份∶ libgnome, libgnomeui, libgnorba 。 libgnome 是个工具函式库,和 Glib 的理念类似,提供的服务包括∶ 组态 (configuration) 载入与存档,启动应用程序, MIME 型别辨识与 metadata 储存。 libgnomeui 部份以提供使用者界面为主,包含 GnomeApp 的 framework , GnomeCanvas , 和许多其他有用的特殊 widgets 。最後一部份 libgnorba 则是经由 CORBA 技术整合 GTK+/GNOME 的应用程序。

当我们设计 GNOME 程序时,很重要的事情是要晓得如何使用 GTK+ 。 所有的 libgnomeui 类别都是以 GTK+ 为基底,因此,使用 libgnomeui 的方式 很类似使用标准的 GTK+ widgets 。

GTK+ 是个 container-based ( 容器为主 ) 的 toolkit 设计,亦即大部份的 widget 都像 「 容器 ( container ) 」 一样可以承载其他 widget 。例如 一个按钮 ( button ) 很可能就是装著一个标签 (label) widget 的 「 容器 」。但也有一些容器只是提供将更多 widgets 放在一起的用途,其中最常用的 是 horizontal box 与 vertical box 将 widgets 排成一列,或是用来格式化 排列的表格。

这样的阶层允许所有的座标动态地计算,即表示你的应用程序在不同的视觉 相关设定下 ( 如字体大小 ) 都能正常运作。并且当视窗改变大小时 ( 或 甚至程序进行国际化 (I18N) 处理後 ) 能适当地重新计算并改变。这也使得 发展在执行时自动产生 GUI 的应用较容易。

当你需要连结一个事件 ( event ) 例如按下按钮,到你指定的动作 ( action ) 例如重绘视窗,你必需用 GTK 特别的讯号 (signal) 机制来 连结事件与自订的函式。例如∶按钮会有「按下」这个讯号让你可以 在使用者按下该按钮时执行连结程序的反应动作。 每一个讯号都是不同的, 宣告讯号的处理函式 (handler functions) 的时候,必须确定用对函式型别。

一个简单的示范程序

接下来我们来看一个简单的示范∶不能免俗地是个 "Hello World" 程序 --- 不过这可不只是普普通通的 "Hello World" 而已,还有功能表选单 (menu) 、 一个 "关於" 的对话窗 (dailog) ,以及状态列 (status bar) 。

这个应用程序有个功能表选单与可分离的子选单,还有可以显示选单提示的 状态列,并且自动储存使用者自订的加速键 ( 热键 ) ,有个标准的 "关於" 盒,另外所有选单的标准项目,还有自动转换语言的能力 ( 试著执行 "LANG=zh_TW.Big5 ./hello_world" ,就会看到正体中文字的选单 ) 。

/* Hello World (Gnome Edition)

* Listing 1

* This code is public domain, so use it as you please.

*/

/* this include will include everything needed for GNOME, including all the

* libraries that gnome needs, such as gtk, imlib, etc ...*/

#include

/* this is usually defined by autoconf but were just using simple makefiles */

#define VERSION "1.0"

/* "callback" function (signal handler) which will quit the application*/

static void

exit_hello(GtkWidget *widget, gpointer data)

{

gtk_main_quit ();

}

/* callback function for when the window closes */

static int

delete_event(GtkWidget *widget, gpointer data)

{

gtk_main_quit ();

return FALSE; /* false means continue with closing the window */

}

/* a callback for the about menu item, it will display a simple "About"

* dialog box standard to all gnome applications

*/

void

about_hello(GtkWidget *widget, gpointer data)

{

GtkWidget *box;

const char *authors[] = {

"James Bond",

NULL

};

box = gnome_about_new(/*title: */ "Hello World (Gnome Edition)",

/*version: */VERSION,

/*copyright: */ "(C) 1999 Secret Agents Inc.",

/*authors: */authors,

/*other comments: */

"An extremely complicated application which "

"does absolutely nothing useful",

NULL);

gtk_widget_show(box);

}

/* define the menus here */

static GnomeUIInfo file_menu [] = {

/* some item which is not one of the standard ones, the null

* would be the callback, however we dont want to really do anything */

GNOMEUIINFO_ITEM_NONE("Something","Just an item which does nothing",NULL),

/* standard exit item */

GNOMEUIINFO_MENU_EXIT_ITEM(exit_hello,NULL),

GNOMEUIINFO_END

};

static GnomeUIInfo help_menu [] = {

/* load the helpfiles for this application if available */

GNOMEUIINFO_HELP("hello_world"),

/* the standard about item */

GNOMEUIINFO_MENU_ABOUT_ITEM(about_hello,NULL),

GNOMEUIINFO_END

};

/* define the main menubar */

static GnomeUIInfo main_menu [] = {

GNOMEUIINFO_MENU_FILE_TREE(file_menu),

GNOMEUIINFO_MENU_HELP_TREE(help_menu),

GNOMEUIINFO_END

};

/* Our main function */

int

main(int argc, char *argv[])

{

GtkWidget *app; /* pointer to our main window */

GtkWidget *w; /* pointer to some widget */

/* initialize gnome */

gnome_init("hello_world", VERSION, argc, argv);

/* create main window */

app = gnome_app_new("hello_world", "Hello World (Gnome Edition)");

/* connect "delete_event" (happens when the window is closed */

gtk_signal_connect(GTK_OBJECT(app), "delete_event",

GTK_SIGNAL_FUNC(delete_event),

NULL);

/* add the menus to the main window */

gnome_app_create_menus(GNOME_APP(app), main_menu);

/* setup appbar (bottom of window bar for status, menu hints and

* progress display) */

w = gnome_appbar_new(FALSE, TRUE, GNOME_PREFERENCES_USER);

gnome_app_set_statusbar(GNOME_APP(app), w);

/* make menu hints display on the appbar */

gnome_app_install_menu_hints(GNOME_APP(app), main_menu);

/* set up some bogus window contents */

w = gtk_label_new(

"Some really really really random\ntext\ngoes\nhere!");

/* add those contents to the window */

gnome_app_set_contents(GNOME_APP(app), w);

/* show all the widgets on the main window and the window itself */

gtk_widget_show_all(app);

/* run the main loop */

gtk_main();

return 0;

}

以下我们来仔细地检视 "Hello World" 程序码,因为有些很容易理解,有些 部份在程序内有注解说明了,我们将专心地研究程序最基础的部份。 在程序码列表的最上方,我们引入 ( include ) gnome.h 这个标头档, 它会再引入其他必要函式库来达成 GNOME 之所有功能。

在主函式(main function)内,这段∶

/* initialize gnome */

gnome_init("hello_world", VERSION, argc, argv);

上面这行初始化所有的 GNOME 函式库, GTK+ ,还有其他必要之函式库, 并且解析 (parse ) 预设的命令列参数。每个 GNOME 程序都得执行这个 初始化动作,没有例外。

在下面一点的地方,你会看到这一段码∶

/* create main window */

app = gnome_app_new("hello_world", "Hello World(Gnome Edition)");

/* connect "delete_event" (happens when the winodw is closed */

gtk_signal_connect(GTK_OBJECT(app), "delete_event",

GTK_SIGNAL_FUNC(delete_event),

NULL);

这段程序码做两件事情,第一件事是建立一个新的应用程序视窗 (main) , 标题是 "Hello World(Gnome Edition)" ,然後将 "app" 指向这新建立的视 窗物件。第二件事情是 (gtk_signal_connect) 指定这个 ("delete_event") 讯号发给物件 "app" 时,应用程序应该连结的处理函式。 当使用者从 window manager 发出关闭视窗的请求时, 该视窗就会收到 "delete_event" 讯号。以下是我们执行的处理函式。

/* callback function for when the window closes */

static int

delete_event(GtkWidget *widget, gpointer data)

{

gtk_main_quit();

return FALSE; /* false means continue with closing the window */

}

上面这段程序码 (gtk_main_quit) 告诉 GTK+ 它要离开主回圈 (main loop) ,然後传回 FALSE 值表示 GTK+ 在关闭後要继续处理。注意到每个讯号都有 自己的型态 ( 每个传回值可代表不同意义,参数也不太一样 ) 。例如从选单 (menu) 上的物件 callback 的处理函式型别长的像这样∶ "void function( GtkWidget *, gopinter data)" ,看一看 GTK+ 和 GNOME 的参考文件 ( 参阅 相关资源 ) 可以帮助你查到所有可用的讯号与其正确的型别。

接下来讲解在 GNOME 的应用程序 framework 下设定选单 (menu) 的方法, 在 GNOME framework 里,选单是 static structure array 的资料结构, 你只要定义好结构,适当栏位里填上正确的值, GNOME framework 就会 建立选单而且帮你连结 (bind) 必要的讯号 (signals) ,为了更简化这过程, 在 libgnomeui/gnome-app-helper.h 里有宣告一些现成的巨集 (macro) 方便快速引用,底下就是 "hello_world" 的选单宣告部份。

static GnomeUIInfo file_menu[]={

/* some item which is not one of the standard ones, the null

* would be the callback, however we dont want to really do anything */

GNOMEUIINFO_ITEM_NONE("Something","Just an item which does nothing", NULL),

/* standard exit item */

GNOMEUIINFO_MENU_EXIT_ITEM(exit_hello,NULL),

GNOMEUIINFO_END

};

static GnomeUIInfo help_menup[]={

/* load the helpfiles for this application if available */

GNOMEUIINFO_HELP("hello)world"),

/* standard about item */

GNOMEUIINFO_MENU_ABOUT_ITEM(about_hello,NULL),

GNOMEUIINFO_END

};

/* define the main menubar */

static GnomeUIInfo main_menu[]={

GNOMEUIINFO_MENU_FILE_TREE(file_menu),

GNOMEUIINFO_MENU_HELP_TREE(help_menu),

GNOMEUIINFO_END

};

第一个 array 定义 "档案"(file) 选单,一般而言, GUI style 强烈建议 应用程序都要有"档案"选单,而且在"档案"选单里有一项可以结束或离开程 式的选项,以引导使用者。我们的"档案"选单里有一个自订的项目,选单中 的标示是 "something" 选项,提示 (hint) 则是 "Just an item which does nothing" 。然而这个选项没有对映的 callback 处理函式 (callback 的参数是 NULL ),所以按下这选项不会有任何动作。"档案"选单里有 (标准的) "离开程序"选项,在

[1] [2] 下一页

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有