GTK+ 2.0 教學-選單元件

有兩種創建選單的方法:一個容易的,一種難的。它們各有各的用處,不過一般你可以使用套件(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選單,包括OpenSaveQuit選項,程式碼將像這樣:

    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() 創建的選單。它可以是一個也被選單欄彈出的選單,範例程式碼裡就做了示範。

感謝你看到這裡,很快就可以離開了,但最好的獎勵行動就是按一下幫我分享或留言,感恩喔~

點我分享到Facebook

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *