工具欄(Toolbars)常用來將一些元件分組,這樣能夠簡化定製它們的外觀和佈局。典型情況下工具欄由帶圖示和標籤以及工具提示的按鈕組成,不過,其它元件也可以放在工具欄裡面。最後,各工具欄組件可以水平或垂直排列,還可以顯示圖示或標籤,或者兩者都顯示。
用下面的函式創建一個工具欄(可能有些人已經猜到了):
GtkWidget *gtk_toolbar_new( void ); |
創建工具欄以後,可以向其中追加、前插和插入工具欄項(這裡意指簡單文字字串)或元素(這裡意指任何元件類型)。要想描述一個工具欄上的物件,需要一個標籤文字、一個工具提示文字、一個私有工具提示文字、一個圖示和一個回呼函式。例如,要前插或追加一個按鈕,應該使用下面的函式:
GtkWidget *gtk_toolbar_append_item( GtkToolbar *toolbar,
const char *text,
const char *tooltip_text,
const char *tooltip_private_text,
GtkWidget *icon,
GtkSignalFunc callback,
gpointer user_data );
GtkWidget *gtk_toolbar_prepend_item( GtkToolbar *toolbar,
const char *text,
const char *tooltip_text,
const char *tooltip_private_text,
GtkWidget *icon,
GtkSignalFunc callback,
gpointer user_data );
|
如果要使用 gtk_toolbar_insert_item(),除上面函式中要指定的參數以外,還要指定插入物件的位置,形式如下:
GtkWidget *gtk_toolbar_insert_item( GtkToolbar *toolbar,
const char *text,
const char *tooltip_text,
const char *tooltip_private_text,
GtkWidget *icon,
GtkSignalFunc callback,
gpointer user_data,
gint position );
|
要簡單地在工具欄項之間添加空白區域,可以使用下面的函式:
void gtk_toolbar_append_space( GtkToolbar *toolbar );
void gtk_toolbar_prepend_space( GtkToolbar *toolbar );
void gtk_toolbar_insert_space( GtkToolbar *toolbar,
gint position );
|
如果需要,工具欄的放置方向和它的式樣可以在不工作時用下面的函式設置:
void gtk_toolbar_set_orientation( GtkToolbar *toolbar,
GtkOrientation orientation );
void gtk_toolbar_set_style( GtkToolbar *toolbar,
GtkToolbarStyle style );
void gtk_toolbar_set_tooltips( GtkToolbar *toolbar,
gint enable );
|
上面的orientation參數取GTK_ORIENTATION_HORIZONTAL或GTK_ORIENTATION_VERTICAL。style參數用於設置工具欄項的外觀,可以取GTK_TOOLBAR_ICONS,GTK_TOOLBAR_TEXT或GTK_TOOLBAR_BOTH。
要想瞭解工具欄還能做什麼,看一看下面的程式(在程式碼之間我們插入了一些解釋):
#include <gtk/gtk.h>
/* 這個函式連接到Close按鈕或者從視窗管理器關閉視窗的事件上 */
gint delete_event (GtkWidget *widget, GdkEvent *event, gpointer data)
{
gtk_main_quit ();
return FALSE;
}
|
上面的程式碼和其它的 GTK 應用程式差別不大,有一點不同的是:我們包含了一個漂亮的 XPM 圖片,用作所有按鈕的圖示。
GtkWidget* close_button; /* 這個按鈕將引發一個信號以
* 關閉應用程式 */
GtkWidget* tooltips_button; /* 啟用/停用工具提示 */
GtkWidget* text_button,
* icon_button,
* both_button; /* 切換工具欄風格的單選按鈕 */
GtkWidget* entry; /* 一個文字輸入元件,用於說明任何元件都可以封裝到
* 工具欄裡 */
|
事實上,不是上面所有的元件都是必須的,我把它們放在一起,是為了讓事情更清晰。
/* 很簡單...當按鈕進行狀態切換時,我們檢查哪一個按鈕是活動的,依此設置工具欄的式樣
* 注意,工具欄是作為用戶資料傳遞到回呼函式的! */
void radio_event (GtkWidget *widget, gpointer data)
{
if (GTK_TOGGLE_BUTTON (text_button)->active)
gtk_toolbar_set_style (GTK_TOOLBAR (data), GTK_TOOLBAR_TEXT);
else if (GTK_TOGGLE_BUTTON (icon_button)->active)
gtk_toolbar_set_style (GTK_TOOLBAR (data), GTK_TOOLBAR_ICONS);
else if (GTK_TOGGLE_BUTTON (both_button)->active)
gtk_toolbar_set_style (GTK_TOOLBAR (data), GTK_TOOLBAR_BOTH);
}
/* 更簡單,檢查給定開關按鈕的狀態,依此啟用或停用工具提示 */
void toggle_event (GtkWidget *widget, gpointer data)
{
gtk_toolbar_set_tooltips (GTK_TOOLBAR (data),
GTK_TOGGLE_BUTTON (widget)->active );
}
|
上面只是當工具欄上的一個按鈕被按下時要呼叫的兩個回呼函式。你應該已經熟悉了這些東西,如果你已經使用過開關按鈕(以及單選按鈕)。
int main (int argc, char *argv[])
{
/* 下面是主視窗(一個對話框)和一個把手盒(handlebox) */
GtkWidget* dialog;
GtkWidget* handlebox;
/* 好了,我們需要一個工具欄,一個帶遮罩(mask)的圖示(所有的按鈕共用一個遮罩)以及
* 一個放圖示的圖示元件(但我們會為每個按鈕創建一個分割元件) */
GtkWidget * toolbar;
GtkWidget * iconw;
/* 這個在所有的 GTK 程式中都被呼叫。 */
gtk_init (&argc, &argv);
/* 用給定的標題和尺寸創建一個新視窗 */
dialog = gtk_dialog_new ();
gtk_window_set_title (GTK_WINDOW (dialog), "GTKToolbar Tutorial");
gtk_widget_set_size_request (GTK_WIDGET (dialog), 600, 300);
GTK_WINDOW (dialog)->allow_shrink = TRUE;
/* 在關閉視窗時退出 */
g_signal_connect (G_OBJECT (dialog), "delete_event",
G_CALLBACK (delete_event), NULL);
/* 需要實現的視窗,因為我們要在它的內容中為工具欄設置圖片 */
gtk_widget_realize (dialog);
/* 我們將工具欄放在一個把手元件(handle box)上,
* 這樣它可以從主視窗上移開 */
handlebox = gtk_handle_box_new ();
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
handlebox, FALSE, FALSE, 5);
|
上面的程式碼和任何其它Gtk應用程示都差不多。它們進行 GTK 初始化,創建主視窗等。唯一需要解釋的是:一個把手盒(a handle box)。把手盒只是一個可以在其中封裝元件的盒子。它和普通盒子的區別在於它能從一個父視窗移開(事實上,把手盒保留在父視窗上,但是它縮小為一個非常小的矩形,同時它的所有內容重新放在一個新的可自由移動的浮動視窗上)。擁有一個可浮動工具欄給人感覺非常好,所以這兩種元件經常同時使用。
/* 工具欄設置為水平的,同時帶有圖示和文字 * 在每個項之間有5像素的間距, * 並且,我們也將它放在把手盒上 */ toolbar = gtk_toolbar_new (); gtk_toolbar_set_orientation (GTK_TOOLBAR (toolbar), GTK_ORIENTATION_HORIZONTAL); gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_BOTH); gtk_container_set_border_width (GTK_CONTAINER (toolbar), 5); gtk_toolbar_set_space_size (GTK_TOOLBAR (toolbar), 5); gtk_container_add (GTK_CONTAINER (handlebox), toolbar); |
上面的程式碼初始化工具欄元件。
/* 工具欄上第一項是<close>按鈕 */
iconw = gtk_image_new_from_file ("gtk.xpm"); /* 圖示元件 */
close_button =
gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), /* 工具欄 */
"Close", /* 按鈕標籤 */
"Closes this app", /* 按鈕的工具提示 */
"Private", /* 工具提示的私有信息 */
iconw, /* 圖示元件 */
GTK_SIGNAL_FUNC (delete_event), /* 一個信號 */
NULL);
gtk_toolbar_append_space (GTK_TOOLBAR (toolbar)); /* 工具欄項後的空白 */
|
在上面的程式碼中,可以看到最簡單的情況:在工具欄上增加一個按鈕。在追加一個新的工具欄項前,必須構造一個圖片(image)元件用作該項的圖示,這個步驟我們要對每一個工具欄項重複一次。在工具欄項之間還要增加間隔空間,這樣後面的工具欄項就不會一個接一個緊挨著。可以看到, gtk_toolbar_append_item()返回一個指向新創建的按鈕元件的指標,所以我們可以用正常的方式使用它。
/* 現在,我們創建單選按鈕組... */
iconw = gtk_image_new_from_file ("gtk.xpm");
icon_button = gtk_toolbar_append_element (
GTK_TOOLBAR (toolbar),
GTK_TOOLBAR_CHILD_RADIOBUTTON, /* 元素類型 */
NULL, /* 指向元件的指標 */
"Icon", /* 標籤 */
"Only icons in toolbar", /* 工具提示 */
"Private", /* 工具提示的私有字串 */
iconw, /* 圖示 */
GTK_SIGNAL_FUNC (radio_event), /* 信號 */
toolbar); /* 信號傳遞的資料 */
gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
|
這裡我們開始創建一個單選按鈕組。用 gtk_toolbar_append_element 就行了。事實上,使用這個函式,我們能夠添加簡單的工具欄項或空白間隔(類型為GTK_TOOLBAR_CHILD_SPACE或GTK_TOOLBAR_CHILD_BUTTON)。在上面的範例中,我們先創建了一個單選按鈕組。要為這個組創建其它單選按鈕,需要一個指向前一個按鈕的指標,這樣按鈕的清單可以很容易組織起來(看在本文件前面部分的單選按鈕節)。
/* 後面的單選按鈕引用前面創建的 */
iconw = gtk_image_new_from_file ("gtk.xpm");
text_button =
gtk_toolbar_append_element (GTK_TOOLBAR (toolbar),
GTK_TOOLBAR_CHILD_RADIOBUTTON,
icon_button,
"Text",
"Only texts in toolbar",
"Private",
iconw,
GTK_SIGNAL_FUNC (radio_event),
toolbar);
gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
iconw = gtk_image_new_from_file ("gtk.xpm");
both_button =
gtk_toolbar_append_element (GTK_TOOLBAR (toolbar),
GTK_TOOLBAR_CHILD_RADIOBUTTON,
text_button,
"Both",
"Icons and text in toolbar",
"Private",
iconw,
GTK_SIGNAL_FUNC (radio_event),
toolbar);
gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (both_button), TRUE);
|
最後,我們必須手工設置其中一個按鈕的狀態(否則它們全部處於活動狀態,並阻止我們在它們之間做出選擇)。
/* 下面只是一個簡單的開關按鈕 */
iconw = gtk_image_new_from_file ("gtk.xpm");
tooltips_button =
gtk_toolbar_append_element (GTK_TOOLBAR (toolbar),
GTK_TOOLBAR_CHILD_TOGGLEBUTTON,
NULL,
"Tooltips",
"Toolbar with or without tips",
"Private",
iconw,
GTK_SIGNAL_FUNC (toggle_event),
toolbar);
gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (tooltips_button), TRUE);
|
開關按鈕的創建方法就很明顯了(如果你已經知道怎麼創建單選按鈕了)。
/* 要將一個元件封裝到工具欄上,只需創建它,然後將它追
* 加到工具欄上,同時設置合適的工具提示 */
entry = gtk_entry_new ();
gtk_toolbar_append_widget (GTK_TOOLBAR (toolbar),
entry,
"This is just an entry",
"Private");
/* 因為它不是工具欄自己創建的,所以我們還需要顯示它 */
gtk_widget_show (entry);
|
可以看到,將任何元件添加到工具欄上都是非常簡單的。唯一要記住的是,這個元件必須手動顯示(與此相反,工具欄自己創建的工具欄項隨工具欄一起顯示)。
/* 好了,現在可以顯示所有的東西了 */ gtk_widget_show (toolbar); gtk_widget_show (handlebox); gtk_widget_show (dialog); /* 進入主循環,等待用戶的操作 */ gtk_main (); return 0; } |
這樣,我們就到了工具欄教學的末尾。當然,還需要一個漂亮的XPM圖示。下面就是:
/* XPM */
static char * gtk_xpm[] = {
"32 39 5 1",
". c none",
"+ c black",
"@ c #3070E0",
"# c #F05050",
"$ c #35E035",
"................+...............",
"..............+++++.............",
"............+++++@@++...........",
"..........+++++@@@@@@++.........",
"........++++@@@@@@@@@@++........",
"......++++@@++++++++@@@++.......",
".....+++@@@+++++++++++@@@++.....",
"...+++@@@@+++@@@@@@++++@@@@+....",
"..+++@@@@+++@@@@@@@@+++@@@@@++..",
".++@@@@@@+++@@@@@@@@@@@@@@@@@@++",
".+#+@@@@@@++@@@@+++@@@@@@@@@@@@+",
".+##++@@@@+++@@@+++++@@@@@@@@$@.",
".+###++@@@@+++@@@+++@@@@@++$$$@.",
".+####+++@@@+++++++@@@@@+@$$$$@.",
".+#####+++@@@@+++@@@@++@$$$$$$+.",
".+######++++@@@@@@@++@$$$$$$$$+.",
".+#######+##+@@@@+++$$$$$$@@$$+.",
".+###+++##+##+@@++@$$$$$$++$$$+.",
".+###++++##+##+@@$$$$$$$@+@$$@+.",
".+###++++++#+++@$$@+@$$@++$$$@+.",
".+####+++++++#++$$@+@$$++$$$$+..",
".++####++++++#++$$@+@$++@$$$$+..",
".+#####+++++##++$$++@+++$$$$$+..",
".++####+++##+#++$$+++++@$$$$$+..",
".++####+++####++$$++++++@$$$@+..",
".+#####++#####++$$+++@++++@$@+..",
".+#####++#####++$$++@$$@+++$@@..",
".++####++#####++$$++$$$$$+@$@++.",
".++####++#####++$$++$$$$$$$$+++.",
".+++####+#####++$$++$$$$$$$@+++.",
"..+++#########+@$$+@$$$$$$+++...",
"...+++########+@$$$$$$$$@+++....",
".....+++######+@$$$$$$$+++......",
"......+++#####+@$$$$$@++........",
".......+++####+@$$$$+++.........",
".........++###+$$$@++...........",
"..........++##+$@+++............",
"...........+++++++..............",
".............++++..............."};
|
2 則留言