天天看點

界面的功能特色---菜單欄和工具欄

版權聲明:您好,轉載請留下本人部落格的位址,謝謝 https://blog.csdn.net/hongbochen1223/article/details/46048153

“菜單”(menubar)是GUI程式中最為常見的部分之一.各種各樣的功能都能使用菜單來實作.

下面這個例子生成一個含有檔案菜單的菜單欄,并且檔案菜單将隻有一個菜單條(menu item).點選之後程式将會退出.

#include <gtk/gtk.h>
int main(int argc,char *argv[])
{
    GtkWidget *window;
    GtkWidget *vbox;
    GtkWidget *menubar;
    GtkWidget *filemenu;
    GtkWidget *file;
    GtkWidget *quit;

    gtk_init(&argc,&argv);
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);
    gtk_window_set_default_size(GTK_WINDOW(window),250,200);
    gtk_window_set_title(GTK_WINDOW(window),"menu");
    vbox = gtk_vbox_new(FALSE,0);
    gtk_container_add(GTK_CONTAINER(window),vbox);
    menubar = gtk_menu_bar_new();
    filemenu = gtk_menu_new();
    file = gtk_menu_item_new_with_label("File");
    quit = gtk_menu_item_new_with_label("Quit");
    gtk_menu_item_set_submenu(GTK_MENU_ITEM(file),filemenu);
    gtk_menu_shell_append(GTK_MENU_SHELL(filemenu),quit);
    gtk_menu_shell_append(GTK_MENU_SHELL(menubar),file);
    gtk_box_pack_start(GTK_BOX(vbox),menubar,FALSE,FALSE,3);
    g_signal_connect_swapped(G_OBJECT(window),"destroy",G_CALLBACK(gtk_main_quit),NULL);
    g_signal_connect(G_OBJECT(quit),"activate",G_CALLBACK(gtk_main_quit),NULL);

    gtk_widget_show_all(window);
    gtk_main();
    return 0;
}
           

在上面生成菜單欄的過程中了解起來可能會有些問題,在GTK中,需要記住的是一個菜單欄和一個菜單的都是源屬于同一個構件的,被稱作菜單外殼(menu shell).菜單選項(menu item)是一個隻對菜單有效的子構件.

menubar = gtk_menu_bar_new();
filemenu = gtk_menu_new();           

這兩行代碼分别生成可一個菜單欄構件和一個菜單構件.

gtk_menu_item_set_submenu(GTK_MNU_ITEM(file),filemenu);           

上面的代碼會生生成一個名為”File”的菜單,這也就是說菜單欄就是一個菜單外殼.很顯然,這裡的檔案菜單也是一個菜單外殼.

gtk_menu_shell_append(GTK_MENU_SHELL(filemenu),quit);
gtk_menu_shell_append(GTK_MENU_SHELL(menubar),file);           

菜單選項有函數gtk_menu_shell_append()來實作,然後一般情況下選項被添加進菜單外殼裡.在這個例子中,

“quit”菜單項被添加到”file”菜單欄中,然後file被添加到menubar中.

現在我們看一下下面幾個函數:

1):

gtk_vbox_new();

我們看一下函數的定義:

GtkWidget *
gtk_vbox_new (gboolean homogeneous, gint spacing);           

該函數會建立一個新的GtkVBox.

參數:

homogeneous: 如果所有的孩子都給予相同的空間配置設定,則該值為TRUE

spacing: ​ ​ ​孩子之間相隔的像素點的個數

下面我們看一下GtkVBox,下面是官方定義:

GtkVBox—-一個縱向的容器盒子

2):

gtk_box_pack_start()

下面我們看一下該函數頭的定義:

void
gtk_box_pack_start (GtkBox *box,
                    GtkWidget *child,
                    gboolean expand,
                    gboolean fill,
                    guint padding);           

該函數用于想box中添加孩子,從盒子的開始連同引用一起打包.就相當于按照添加的順序一個一個打包,從盒子的開始.

​box: ​一個GtkBox

​child: ​被添加到box的GtkWidget

​expand: 如果新的孩子被給予額外的盒子的空間,該值為TRUE.額外的空間将會在所有使用這個選項的孩子之間平均配置設定

​fill: 如果被expand選項給予孩子的空間實際上就是配置設定給孩子的空間的話,該值為TRUE.當expand設定為FALSE的時候,​這個值是沒有用的.

​padding: 在這個孩子和他的鄰居之間設定的以像素為機關的額外空間.

3):

g_signal_connect()和g_signal_connect_swapped()的差別,這個在後面讨論,i敬請期待.

先看一下我的程式運作的結果:

下面是生成的帶有快捷方式和圖像的菜單欄,至于其添加的方式我們後面了解,先看一下我的代碼:

#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
int main(int argc,char *argv[])
{
    GtkWidget *window;
    GtkWidget *vbox;
    GtkWidget *menubar;
    GtkWidget *filemenu;
    GtkWidget *file;
    GtkWidget *new;
    GtkWidget *open;
    GtkWidget *quit;
    GtkWidget *sep;

    GtkAccelGroup *accel_group = NULL;
    gtk_init(&argc,&argv);
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);
    gtk_window_set_default_size(GTK_WINDOW(window),250,200);
    gtk_window_set_title(GTK_WINDOW(window),"menu");
    vbox = gtk_vbox_new(FALSE,0);
    gtk_container_add(GTK_CONTAINER(window),vbox);
    menubar = gtk_menu_bar_new();

    filemenu = gtk_menu_new();

    accel_group = gtk_accel_group_new();
    gtk_window_add_accel_group(GTK_WINDOW(window),accel_group);

    file = gtk_menu_item_new_with_label("_File");
    new = gtk_image_menu_item_new_from_stock(GTK_STOCK_NEW,NULL);
    open = gtk_image_menu_item_new_from_stock(GTK_STOCK_OPEN,NULL);
    sep = gtk_separator_menu_item_new();

    quit = gtk_image_menu_item_new_from_stock(GTK_STOCK_QUIT,accel_group);
    gtk_widget_add_accelerator(quit,"activate",accel_group,GDK_q,GDK_CONTROL_MASK,
    GTK_ACCEL_VISIBLE);
    gtk_menu_item_set_submenu(GTK_MENU_ITEM(file),filemenu);
    gtk_menu_shell_append(GTK_MENU_SHELL(filemenu),new);
    gtk_menu_shell_append(GTK_MENU_SHELL(filemenu),open);
    gtk_menu_shell_append(GTK_MENU_SHELL(filemenu),sep);
    gtk_menu_shell_append(GTK_MENU_SHELL(filemenu),quit);
    gtk_menu_shell_append(GTK_MENU_SHELL(menubar),file);
    gtk_box_pack_start(GTK_BOX(vbox),menubar,FALSE,FALSE,3);
    g_signal_connect_swapped(G_OBJECT(window),"destroy",G_CALLBACK(gtk_main_quit),NULL);
    g_signal_connect(G_OBJECT(quit),"activate",G_CALLBACK(gtk_main_quit),NULL);
    gtk_widget_show_all(window);
    gtk_main();

    return 0;
}
           

下面是我的程式運作後,菜單欄打開後的效果:

未完,待續!!