GTK+ 2.0 教学-使用ItemFactory

注:这一节是我新译的因为简体版的没有翻译这一篇,如果有翻的不妥处尚请指教。

现在我们已经介绍了难的办法,这里介绍怎样用 gtk_item_factory 呼叫来做。ItemFactory 从ItemFactory entries的阵列中创建选单,他的意思就是你可以用最简单的格式来定义你的选单然后用最少的函式呼叫创建选单/功能栏元件。

ItemFactory entries

ItemFactory 的核心就是 ItemFactoryEntry,这个结构定义了一个选单项并且当这些项目的阵列定义之后整个选单就形成了,ItemFactory entry struct 定义看起来像这样:

struct _GtkItemFactoryEntry{gchar *path;gchar *accelerator;  GtkItemFactoryCallback callback;guint                  callback_action;

gchar          *item_type;

};

每个栏位定义了部分的选单项。

*path 是一个字串定义了选单项的名称及路径,举个例来说,”/File/Open” 是选单项的名字,这个名字归入在 ItemFactory entry 的路径”/File”里,但是注意”/File/Open” 会出现在 File 选单中的”Open”功能栏,另外要注意”/”被用来定义选单的路径,字母前面加底线表示他是快捷键当选单开启时就可以用。

*accelerator 是一个字串用来说明该选单项目的快捷建的组合键,这个字串是由单一字元或是单一字元的辅助按键的组合所做成,大小写不区分。

可用的辅助按键有:

"<ALT>                             - alt"<CTL>" or "<CTRL>" or "<CONTROL>" - control"<MOD1>" to "<MOD5>"               - modn"<SHFT>" or "<SHIFT>"              - shift

范例:

"<ConTroL>a""<SHFT><ALT><CONTROL>X"

callback 是当选单项目引发”activate”信号时被呼叫的函式,回呼函式的格式在后面回呼函式的描述中讨论。

callback_action 的值会传给回呼函式,他也会影响函式的原型(prototype)在回呼函式的描述中说明。

item_type 是一个字串定义了元件被封装入选单项目容器中的型别,它像这样:

NULL or "" or "<Item>" - create a simple item"<Title>"              - create a title item"<CheckItem>"          - create a check item"<ToggleItem>"         - create a toggle item"<RadioItem>"          - create a (root) radio item

"Path"                 - create a sister radio item

"<Tearoff>"            - create a tearoff

"<Separator>"          - create a separator

"<Branch>"             - create an item to hold submenus (optional)

"<LastBranch>"         - create a right justified branch

"<StockItem>"          - create a simple item with a stock image.

see gtkstock.h for builtin stock items

注意 <LastBranch> 只有在功能栏的子选单中有效。

 

回呼函式的描述

ItemFactory entry 的回呼函式有两种格式,假如 callback_action 是0,格式如下:

void callback( void )

另外的格式如下:

void callback( gpointer    callback_data,               guint       callback_action,GtkWidget  *widget )

callback_data 任意资料的指标,它在呼叫gtk_item_factory_create_items()时被设定。

callback_action 跟在ItemFactory entry里的callback_action 值一样。

*widget 是选单项目元件的指标 (在选单元件中有讨论)。

 

ItemFactory entry 范例

创建简单的选单项目:

GtkItemFactoryEntry entry = {"/_File/_Open...", "<CTRL>O", print_hello, 			0, "<Item>"};

这一行定义了一个简单的选单项目 “/File/Open” (会显示 “Open”),在 “/File” 选单项目下,当按下呼叫函式print_hello()时它有快捷键 control+’O’ , print_hello() 的格式是 void print_hello(void) 因为它的 callback_action 栏位是0,当”Open”的 ‘O’ 被加底线显示时以及在荧幕上按下’O’时选单项目是可见的时候会启用它们,注意 “File/_Open” 也可以用来替换 “/_File/_Open”。

用更复杂的回呼函式来创建项目:

GtkItemFactoryEntry entry = {"/_View/Display _FPS", NULL, print_state, 			7,"<CheckItem>"};

这一行定义了一个新的选单项目会显示 “Display FPS” 在”View”的选单项目下,当按下 print_state() 函式时会被呼叫,因为 callback_action 不是0所以 print_state() 格式是这样:

void print_state( gpointer    callback_data,                  guint       callback_action,GtkWidget  *widget )

callback_action 的值是 7。

创建圆钮集:

GtkItemFactoryEntry entry1 = {"/_View/_Low Resolution", NULL, change_resolution, 			1, "<RadioButton>"};GtkItemFactoryEntry entry2 = {"/_View/_High Resolution", NULL, change_resolution,2, "/View/Low Resolution"};

entry1 定义了一个单一的圆钮当处变呼叫函式change_resolution() 的参数时 callback_action 等于1。 change_resolution() 的格式:

void change_resolution(gpointer    callback_data,                       guint       callback_action,GtkWidget  *widget)

entry2 定义了一个圆钮,这个圆钮属于entry1所属的圆钮这组,它呼叫相同的函式但是参数 callback_action 等于 2,注意entry2的 item_type 是没有 (‘_’)的快速键的entry1的路径,假如另一个圆钮需要在相同的组合中那么他可以用相同的方式来定义就像 entry2item_type 而他的值是 “/View/Low Resolution”。

 

ItemFactoryEntry 阵列

ItemFactoryEntry 在它自己上不是很有用,entries的阵列是需要定义的,下面是你如何宣告这阵列的范例。

static GtkItemFactoryEntry entries[] = {  { "/_File",         NULL,      NULL,         0, "<Branch>" },{ "/File/tear1",    NULL,      NULL,         0, "<Tearoff>" },{ "/File/_New",     "<CTRL>N", new_file,     1, "<Item>" },{ "/File/_Open...", "<CTRL>O", open_file,    1, "<Item>" },

{ "/File/sep1",     NULL,      NULL,         0, "<Separator>" },

{ "/File/_Quit",    "<CTRL>Q", quit_program, 0, "<StockItem>", GTK_STOCK_QUIT } };

 

创建一个 ItemFactory

GtkItemFactoryEntry 项目的阵列定义了选单,一旦阵列被定义这个 item factory 就会被创建,这个函式可以这样用:

GtkItemFactory* gtk_item_factory_new( GtkType        container_type,                                      const gchar   *path,GtkAccelGroup *accel_group );

container_type 可以是下列其中一个值:

GTK_TYPE_MENUGTK_TYPE_MENU_BARGTK_TYPE_OPTION_MENU

container_type 定义了你要的选单型态,所以当你撷取它的时候,它不是选单 (例如弹出式)就是选项选单 (像是复合方块但是有下拉选单)。

path 定义选单的根的路径,基本上它是选单根的名称,必需用”<>”括起来,这对快捷键的名称来说很重要而且应该是唯一的,每个选单和每个程式之间也应该是唯一的, 举个例来说一个程式名称叫 ‘foo’,它的主选单就应该叫做 “<FooMain>”,而弹出选单 “<FooImagePopUp>”或者类似,很重要的一个地方就是这些名称都是唯一的。

accel_group 是一个gtk_accel_group的指标,item factory 会在产生选单时设定快捷键表格,新的快捷键组合由 gtk_accel_group_new()产生。

但这只是第一步,要转换 GtkItemFactoryEntry 资讯的阵列到元件会使用下列的函式:

void gtk_item_factory_create_items( GtkItemFactory      *ifactory,                                    guint                n_entries,GtkItemFactoryEntry *entries,gpointer             callback_data );

*ifactory 是上面产生的 item factory 指标。

n_entries 是GtkItemFactoryEntry 阵列的项目数目。

*entries 是GtkItemFactoryEntry 阵列的指标。

callback_data 是所有callback_action != 0时传给回呼函式的资料。

快捷键组现在已形成,所以你可能要连结它到视窗这个选单在里面:

void gtk_window_add_accel_group( GtkWindow     *window,                                 GtkAccelGroup *accel_group);

 

使用选单及选单项目

最后要做的就是使用选单,下列的函式从ItemFactory撷取相关的元件:

GtkWidget* gtk_item_factory_get_widget( GtkItemFactory *ifactory,                                        const gchar    *path );

举例来说假如有一个 ItemFactory 有两个项目 “/File” 及 “/File/New”,使用 “/File” 路径会从ItemFactory 撷取一个 menu 元件,使用 “/File/New” 路径会撷取一个选单项目元件, 这使得它可以设定选单项目的初始状态,举个例来说要设初始的圆钮项目到 “/Shape/Oval” 路径的其中一个可以使用下面的程式码:

gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM (gtk_item_factory_get_item (item_factory, "/Shape/Oval")),TRUE);

最后要撷取选单的根使用 gtk_item_factory_get_item() 有 “<main>” 的路径(或是使用gtk_item_factory_new() 而不管其路径), 在 ItemFactory拥有型别 GTK_TYPE_MENU_BAR 产生的情况下会传回功能栏元件,使用型别 GTK_TYPE_MENU 会传回选单元件, 使用型别 GTK_TYPE_OPTION_MENU 会传回选项选单元件。

记得 “/_File” 路径定义的项目在这里真的是 “/File”。

现在你有 功能栏 或 选单 这些元件同样也可以在 选单元件 这一节所讨论的方式来处理。

Comments are closed.