有两种创建选单的方法:一个容易的,一种难的。它们各有各的用处,不过一般你可以使用套件(Itemfactory)(容易的方法)。“难”的方法是直接使用呼叫来创建所有的选单。容易的方法是使用 gtk_item_factory 呼叫。这要简单得多,但每种方法各有优点和缺点。
套件要容易使用得多,加新的选单也方便些,虽然用手动方法写一些外包(wrapper)函式来创建选单能对可用性大有帮助。使用套件,不能在选单上增加图片或 ‘/’ 字符。
手动创建选单
按照现实教学中的惯例,我们将先介绍难的方法。
创建选单栏和子选单时要用到三种元件:
- 一个选单项(menu item),就是用户要选择的东西,比如,”Save”
- 一个选单(menu),作为选单项的容器,以及
- 一个选单栏(menubar),是各个单独选单的容器。
选单项元件有两个不同的用处,这情况有一点复杂。既有封装到选单里的元件,也有封装到选单栏中,当被选中时启用选单的元件。
让我们看一下用来创建选单和选单栏的函式。第一个函式用来创建一个新的选单栏。
GtkWidget *gtk_menu_bar_new( void ); |
这个不太需要加以说明的函式创建一个新的选单栏。你用 gtk_container_add() 封装它到一个视窗,或盒组装(box_pack)函式来将它封装到一个盒子中 - 就像按钮一样。
GtkWidget *gtk_menu_new( void ); |
这个函式传回指向一个新选单的指标。它从不会真正显示(用 gtk_widget_show()),它只是一个选单项的容器。我希望你看了后面的范例后会弄清楚一些。
接下来的三个呼叫用来创建被封装到选单(和选单栏)中的选单项。
GtkWidget *gtk_menu_item_new( void ); GtkWidget *gtk_menu_item_new_with_label( const char *label ); GtkWidget *gtk_menu_item_new_with_mnemnonic( const char *label ); |
这些呼叫用来创建将显示的选单项。记住要区别用 gtk_menu_new() 创建的“选单”和用 gtk_menu_item_new() 函式创建的“选单项”。有了相关联动作的选单项将是一个真实的按钮,而选单将是一个包含选单项的容器。
gtk_menu_item_new_with_label() 和 gtk_menu_item_new() 函式正如你读了按钮部分后料想的一样。其一创建一个已经有一个标签封封装进来了的新的选单项,另一个仅仅创建一个空白的选单项。
在创建一个选单项后你要将它放到一个选单里。用函式 gtk_menu_append 就行了。为了撷取何时这个项被用户选中,我们要用平常的方法连接到activate信号。所以,如果我们要创建一个标准的File选单,包括Open,Save和Quit选项,程式码将像这样:
file_menu = gtk_menu_new (); /* 不必显示选单 */
/* 创建选单项 */
open_item = gtk_menu_item_new_with_label ("Open");
save_item = gtk_menu_item_new_with_label ("Save");
quit_item = gtk_menu_item_new_with_label ("Quit");
/* 将它们加到选单中 */
gtk_menu_append (GTK_MENU (file_menu), open_item);
gtk_menu_append (GTK_MENU (file_menu), save_item);
gtk_menu_append (GTK_MENU (file_menu), quit_item);
/* 将回呼函式系结到activate信号 */
g_signal_connect_swapped (G_OBJECT (open_item), "activate",
G_CALLBACK (menuitem_response),
(gpointer) "file.open");
g_signal_connect_swapped (G_OBJECT (save_item), "activate",
G_CALLBACK (menuitem_response),
(gpointer) "file.save");
/* 我们可以系结Quit选单项到我们的退出函式 */
g_signal_connect_swapped (G_OBJECT (quit_item), "activate",
G_CALLBACK (destroy),
(gpointer) "file.quit");
/* 一定要显示选单项 */
gtk_widget_show (open_item);
gtk_widget_show (save_item);
gtk_widget_show (quit_item);
|
这时我们有了我们的选单。现在我们要创建一个选单栏,并为File项目(entry)创建一个选单项,我们的选单就加在这个上。程式码看起来像这样:
menu_bar = gtk_menu_bar_new ();
gtk_container_add (GTK_CONTAINER (window), menu_bar);
gtk_widget_show (menu_bar);
file_item = gtk_menu_item_new_with_label ("File");
gtk_widget_show (file_item);
|
现在我们要把选单和file_item关联起来。用这个函式可以做到:
void gtk_menu_item_set_submenu( GtkMenuItem *menu_item,
GtkWidget *submenu );
|
那么,我们的范例接下来就是
gtk_menu_item_set_submenu (GTK_MENU_ITEM (file_item), file_menu); |
所有剩下要做的就是将选单加到选单栏,用这个函式完成:
void gtk_menu_bar_append( GtkMenuBar *menu_bar,
GtkWidget *menu_item );
|
在我们的情况下就像这样了:
gtk_menu_bar_append (GTK_MENU_BAR (menu_bar), file_item); |
如果我们想让选单在选单栏上右对齐,例如帮助选单就经常是这样,我们可以在系结它到选单栏之前使用下面的函式(本例中又是对file_item使用)。
void gtk_menu_item_right_justify( GtkMenuItem *menu_item ); |
这里是一个对创建一个附带了选单的选单栏所需步骤的概要:
- 用 gtk_menu_new() 创建一个新的选单
- 多次呼叫 gtk_menu_item_new() 创建每个你想在你的选单上出现的选单项。并使用 gtk_menu_append() 将每个新的选单项放到选单上。
- 用 gtk_menu_item_new() 创建一个选单项。这将是选单的根(root),这里所显示的文字就是选单栏上出现的字。
- 用 gtk_menu_item_set_submenu() 将选单系结到根选单项(就是上一步创建的那个)。
- 用 gtk_menu_bar_new 创建一个新的选单栏。在一个选单栏上创建一系列选单时这步只要做一次就行了。
- 用 gtk_menu_bar_append() 将根选单项放到选单栏上。
创建一个弹出选单几乎也一样。不同的是选单不会被选单栏“自动”弹出,而是在button-press事件(例如)里呼叫函式 gtk_menu_popup() 时明确地弹出。有这些步骤:
- 创建一个事件处理函式。它要有如下原型:
static gint handler (GtkWidget *widget, GdkEvent *event);并且它会根据event得到选单弹出的地方。
- 在事件处理函式里,如果这是一个滑鼠按钮按下事件,把event当作滑鼠按键事件(本来就是)并像范例程式码那样利用它传递讯息给gtk_menu_popup()。
- 系结那个事件处理函式到一个元件用
g_signal_connect_swapped (G_OBJECT (widget), "event", G_CALLBACK (handler), G_OBJECT (menu));其中widget是你要系结到的元件,handler是处理函式,而menu是一个用 gtk_menu_new() 创建的选单。它可以是一个也被选单栏弹出的选单,范例程式码里就做了示范。
3 則留言
Comments are closed.