gtk學習總結:GTK從入門到放棄,三天包教包會
阿新 • • 發佈:2019-01-06
今天花了一些時間複習之前學習過的gtk,感覺東西光學不用忘得好快啊,在這做個之前學過的內容的備份,希望對大家有用,也希望大家不要從入門到放棄。文中有些程式碼例子可能來自《GTK從入門到精通》吧,我不記得了,或者叫《GTK中文教程》,忘記了,總之,這是一個學習筆記,希望不觸及任何人的利益,起到共享學習之用。
目錄
16.文字輸入gtk_entry_new:可見/不可見,可輸入/不可輸入
規定最大長度的gtk_entry_new_with_max_length
17.檔案選擇:gtk_file_selection_new
20.一個簡單的frame:gtk_frame_new(不同於java的JFrame)
gtk_aspect_frame_new:更多選項的frame
21.滾動視窗:gtk_scrolled_window_new
24.畫圖介面:gdk_draw_arc,gdk_draw_rectangle
30.模擬90坦克遊戲:在frame中移動一個圖片,鍵盤控制走向
33.分隔面板:gtk_hpanel_new,gtk_vpanel_new(未編譯)
35.字型選擇:gtk_font_selection_dialog_new
36.幾個畫圖的騷操作:gtk_drawing_area_new
編譯方法
$ gcc main.c `pkg-config --libs --cflags gtk+-3.0`
或者使用gtk-2.0。
編譯指令碼
#!/bin/bash
if [ $# -lt 1 ]; then
echo "usage: $0 [main.c]"
exit
fi
gcc -o a $1 `pkg-config --libs --cflags gtk+-2.0`
01.一個簡單的按鈕
#include <gtk/gtk.h>
//#include "temp.c"
/* 這是一個回撥函式。data 引數在本示例中被忽略。
* 後面有更多的回撥函式示例。*/
void hello( GtkWidget *widget, gpointer data )
{
g_print ("Hello World\n");//temp(data );
}
gint delete_event( GtkWidget *widget, GdkEvent *event, gpointer data )
{
/* 如果你的 "delete_event" 訊號處理函式返回 FALSE,GTK 會發出 "destroy" 訊號。
* 返回 TRUE,你不希望關閉視窗。
* 當你想彈出“你確定要退出嗎?”對話方塊時它很有用。*/
g_print ("delete event occurred\n");
/* 改 TRUE 為 FALSE 程式會關閉。*/
return FALSE;
}
/* 另一個回撥函式 */
void destroy( GtkWidget *widget, gpointer data )
{
gtk_main_quit ();
}
int main( int argc, char *argv[] )
{
/* GtkWidget 是構件的儲存型別 */
GtkWidget *window;
GtkWidget *button;
/* 這個函式在所有的 GTK 程式都要呼叫。引數由命令列中解析出來並且送到該程式中*/
gtk_init (&argc, &argv);
/* 建立一個新視窗 */
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
/* 當視窗收到 "delete_event" 訊號 (這個訊號由視窗管理器發出,通常是“關閉”
* 選項或是標題欄上的關閉按鈕發出的),我們讓它呼叫在前面定義的 delete_event() 函式。
* 傳給回撥函式的 data 引數值是 NULL,它會被回撥函式忽略。*/
g_signal_connect (G_OBJECT (window), "delete_event",
G_CALLBACK (delete_event), NULL);
/* 在這裡我們連線 "destroy" 事件到一個訊號處理函式。
* 對這個視窗呼叫 gtk_widget_destroy() 函式或在 "delete_event" 回撥函式中返回 FALSE 值
* 都會觸發這個事件。*/
g_signal_connect (G_OBJECT (window), "destroy",
G_CALLBACK (destroy), NULL);
/* 設定視窗邊框的寬度。*/
gtk_container_set_border_width (GTK_CONTAINER (window), 10);
/* 建立一個標籤為 "Hello World" 的新按鈕。*/
button = gtk_button_new_with_label ("Hello World");
/* 當按鈕收到 "clicked" 訊號時會呼叫 hello() 函式,並將NULL傳給
* 它作為引數。hello() 函式在前面定義了。*/
g_signal_connect (G_OBJECT (button), "clicked",
G_CALLBACK (hello), "1");
/* 當點選按鈕時,會通過呼叫 gtk_widget_destroy(window) 來關閉視窗。
* "destroy" 訊號會從這裡或從視窗管理器發出。*/
// g_signal_connect_swapped (G_OBJECT (button), "clicked",
// G_CALLBACK (gtk_widget_destroy),window);
/* 把按鈕放入視窗 (一個 gtk 容器) 中。*/
gtk_container_add (GTK_CONTAINER (window), button);
/* 最後一步是顯示新建立的按鈕和視窗 */
gtk_widget_show (button);
gtk_widget_show (window);
/* 所有的 GTK 程式必須有一個 gtk_main() 函式。程式執行停在這裡
* 等待事件 (如鍵盤事件或滑鼠事件) 的發生。*/
gtk_main ();
return 0;
}
02.兩個按鈕
#include <gtk/gtk.h>
/* 我們新改進的回撥函式。傳遞到該函式的資料將列印到標準輸出(stdout)。*/
void callback( GtkWidget *widget, gpointer data )
{
g_print ("%s ", (gchar *) data);
}
/* 另一個回撥函式 */
gint delete_event( GtkWidget *widget, GdkEvent *event, gpointer data )
{
gtk_main_quit ();
return FALSE;
}
int main( int argc, char *argv[] )
{
/* GtkWidget 是構件的儲存型別 */
GtkWidget *window;
GtkWidget *button;
GtkWidget *box1;
gtk_init (&argc, &argv);
/* 建立一個新視窗 */
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
/* 這是一個新的呼叫,設定視窗標題為"Hello Buttons!" */
gtk_window_set_title (GTK_WINDOW (window), "Hello Buttons!");
/* 在這裡我們為 delete_event 設定了一個處理函式來立即退出 GTK。*/
g_signal_connect (G_OBJECT (window), "delete_event",
G_CALLBACK (delete_event), NULL);
/* 設定視窗邊框的寬度。 */
gtk_container_set_border_width (GTK_CONTAINER (window), 20);
/* 我們建立了一個組裝盒。詳情參見“組裝”章節。我們看不見組裝盒,它僅被作為排列構件的工具。*/
box1 = gtk_hbox_new (FALSE, 1);
/* 把組裝盒放入主視窗中。*/
gtk_container_add (GTK_CONTAINER (window), box1);
/* 建立一個標籤為 "Button 1" 的新按鈕。*/
button = gtk_button_new_with_label ("Hello");
/* 當按鈕被按下時,我們呼叫 "callback" 函式,並將一個指向 "button 1" 的指標作為它的引數。*/
g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (callback), "hello");
/* 代替 gtk_container_add,我們把按鈕放入不可見的組裝盒,該組合盒已經組裝進視窗中了。*/
gtk_box_pack_start (GTK_BOX(box1), button, TRUE, TRUE, 0);
/* 總是記住這一步,它告訴 GTK 我們為這個按鈕做的準備工作已經完成了,現在可以顯示它了。*/
gtk_widget_show (button);
/* 同樣建立第二個按鈕。*/
button = gtk_button_new_with_label ("World");
g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (callback), "World");
gtk_box_pack_start(GTK_BOX (box1), button, TRUE, TRUE, 0);
gtk_widget_show (button);
/* 同樣建立第3個按鈕。*/
button = gtk_button_new_with_label ("!");
g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (callback), "!");
gtk_box_pack_start(GTK_BOX (box1), button, TRUE, TRUE, 0);
gtk_widget_show (button);
gtk_widget_show (box1);
gtk_widget_show (window);
/* 停在這裡等待事件發生。*/
gtk_main ();
return 0;
}
03.vbox:一張圖片+一個按鈕
/* 建立SPLASH視窗 splash.c */
#include <gtk/gtk.h>
//主函式
int main (int argc,char* argv[])
{
GtkWidget* window ;
GtkWidget* vbox ;
GtkWidget* image ;
GtkWidget* button ;
gtk_init(&argc,&argv);
window = gtk_window_new(GTK_WINDOW_POPUP);//////////no boundary
gtk_window_set_title(GTK_WINDOW(window),"Splash視窗");
g_signal_connect(G_OBJECT(window),"destroy",
G_CALLBACK(gtk_main_quit),NULL);
//gtk_container_set_border_width(GTK_CONTAINER(window),20);
//gtk_window_set_default_size(GTK_WINDOW(window),500,400);
//gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);
vbox = gtk_vbox_new(FALSE,0);
gtk_container_add(GTK_CONTAINER(window),vbox);
image = gtk_image_new_from_file("b.png");
gtk_box_pack_start(GTK_BOX(vbox),image,FALSE,FALSE,0);
button = gtk_button_new_with_label("Splash視窗");
g_signal_connect(G_OBJECT(button),"clicked",
G_CALLBACK(gtk_main_quit),NULL);
gtk_box_pack_start(GTK_BOX(vbox),button,FALSE,FALSE,0);
gtk_widget_show_all(window);
gtk_main();
return FALSE;
}
04.一個簡單的提示視窗:下一步+上一步+確定
/* 每日提示 tips.c */
#include <gtk/gtk.h>
//XPM格式的影象資料,以C語言原始碼形式存於檔案中
static char * book_open_xpm[] = {
"16 16 4 1",
" c None s None",
". c black",
"X c #808080",
"o c white",
" ",
" .. ",
" .Xo. ... ",
" .Xoo. ..oo. ",
" .Xooo.Xooo... ",
" .Xooo.oooo.X. ",
" .Xooo.Xooo.X. ",
" .Xooo.oooo.X. ",
" .Xooo.Xooo.X. ",
" .Xooo.oooo.X. ",
" .Xoo.Xoo..X. ",
" .Xo.o..ooX. ",
" .X..XXXXX. ",
" ..X....... ",
" .. ",
" "};
//自定義提示資訊
static gchar *info[5] = {
"此軟體用於測試每日提示功能的實現,如果你發現問題請及時回覆。",
"我們的目的是把GTK+2.0的大多數功能奉獻給每一位自由軟體愛好者和開發者。",
"每一位Linux的支持者都會讓我們增加一分信心,Linux最終仍是臺式計算機作業系統。",
"計算機軟體技術是一種科學技術,它和人類歷史上其他的科學技術一樣,是允許每一人自由使用的。",
"當前你測試完此程式後,請設法把它附加到你創作的軟體當中去,這是你成功的第一步。"
};
static GtkWidget *window; //主視窗
static GtkWidget *frame; //框架
static GtkWidget *pre_button; //上一提示按鈕
static GtkWidget *next_button; //下一提示按鈕
static GtkWidget *label; //提示資訊內容標籤
static GtkWidget *title; //框架的標題
gint current_info = 0 ;//當前提示資訊計數
GtkWidget* create_title (GtkWidget *data)
{ //建立框架控制元件的標題
GtkWindow *title;
GtkWidget *hbox;
GtkWidget *image;
GtkWidget *label;
GdkPixmap *pixmap;
GdkBitmap *mask;
pixmap = gdk_pixmap_create_from_xpm_d(
data->window,&mask,
>K_WIDGET(data)->style->white,
book_open_xpm);
image = gtk_image_new_from_pixmap(pixmap,NULL);
label = gtk_label_new("新的標題");
hbox = gtk_hbox_new(FALSE,0);
gtk_box_pack_start(GTK_BOX(hbox),image,FALSE,FALSE,2);
gtk_box_pack_start(GTK_BOX(hbox),label,FALSE,FALSE,2);
return hbox ;
}
GtkWidget* create_button (gchar* stockid,gchar* title)
{ //建立帶影象的按鈕
GtkWidget *button;
GtkWidget *image;
GtkWidget *label;
GtkWidget *hbox;
image = gtk_image_new_from_stock(stockid,GTK_ICON_SIZE_MENU);
label = gtk_label_new(title);
hbox = gtk_hbox_new(FALSE,0);
gtk_box_pack_start(GTK_BOX(hbox),image,FALSE,FALSE,3);
gtk_box_pack_start(GTK_BOX(hbox),label,FALSE,FALSE,3);
button = gtk_button_new();
gtk_container_add(GTK_CONTAINER(button),hbox);
return button;
}
void pre_info (GtkButton *button,gpointer data)
{ //上一提示
gint i ;
i = current_info - 1 ;
if(i == -1) return ;
if(i == 0 ) gtk_widget_set_sensitive(pre_button,FALSE);
current_info = i ;
gtk_widget_set_sensitive(next_button,TRUE);
gtk_label_set_text(GTK_LABEL(label),info[current_info]);
}
void next_info (GtkButton *button,gpointer data)
{ //下一提示
gint i ;
i = current_info + 1 ;
if(i == 5) return ;
if(i == 4) gtk_widget_set_sensitive(next_button,FALSE);
current_info = i ;
gtk_widget_set_sensitive(pre_button,TRUE);
gtk_label_set_text(GTK_LABEL(label),info[current_info]);
}
int main ( int argc , char* argv[])
{
GtkWidget *hbox ;
GtkWidget *vbox;
GtkWidget *bbox;
GtkWidget *button;
GtkWidget *image;
GtkWidget *title;
gtk_init(&argc,&argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
g_signal_connect(G_OBJECT(window),"delete_event",
G_CALLBACK(gtk_main_quit),NULL);
gtk_window_set_title(GTK_WINDOW(window),"每日提示");
gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);
gtk_container_set_border_width(GTK_CONTAINER(window),10);
gtk_widget_realize(window);
vbox = gtk_vbox_new(FALSE,0);
gtk_container_add(GTK_CONTAINER(window),vbox);
hbox = gtk_hbox_new(FALSE,0);
gtk_box_pack_start(GTK_BOX(vbox),hbox,TRUE,TRUE,5);
image = gtk_image_new_from_file("l.bmp");
gtk_box_pack_start(GTK_BOX(hbox),image,FALSE,FALSE,5);
frame = gtk_frame_new(NULL);
title = create_title(window);
gtk_frame_set_label_widget(GTK_FRAME(frame),title);
gtk_box_pack_start(GTK_BOX(hbox),frame,TRUE,TRUE,5);
label = gtk_label_new(NULL);
gtk_label_set_text(GTK_LABEL(label),info[0]);
gtk_label_set_line_wrap(GTK_LABEL(label),TRUE);
gtk_container_add(GTK_CONTAINER(frame),label);
bbox = gtk_hbutton_box_new();
gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox),GTK_BUTTONBOX_END);
gtk_box_set_spacing(GTK_BOX(bbox),5);
gtk_box_pack_start(GTK_BOX(vbox),bbox,FALSE,FALSE,5);
button = gtk_check_button_new_with_label("每次啟動時顯示");
gtk_box_pack_start(GTK_BOX(bbox),button,FALSE,FALSE,5);
pre_button = create_button(GTK_STOCK_GO_BACK,"上一提示");
gtk_widget_set_sensitive(pre_button,FALSE);
g_signal_connect(G_OBJECT(pre_button),"clicked",
G_CALLBACK(pre_info),NULL);
gtk_box_pack_start(GTK_BOX(bbox),pre_button,FALSE,FALSE,5);
next_button = create_button(GTK_STOCK_GO_FORWARD,"下一提示");
g_signal_connect(G_OBJECT(next_button),"clicked",
G_CALLBACK(next_info),NULL);
gtk_box_pack_start(GTK_BOX(bbox),next_button,FALSE,FALSE,5);
button = gtk_button_new_from_stock(GTK_STOCK_OK);
g_signal_connect(G_OBJECT(button),"clicked",
G_CALLBACK(gtk_main_quit),NULL);
gtk_box_pack_start(GTK_BOX(bbox),button,FALSE,FALSE,5);
gtk_widget_show_all(window);
gtk_main();
return FALSE;
}
效果:
05.多按鈕:一個簡單的鍵盤
#include <gtk/gtk.h>
/* 我們的回撥。
* 傳到這個函式的資料被列印到標準輸出 */
void callback( GtkWidget *widget, gpointer data )
{
g_print ("%s", (char *) data);
}
/* 這個回撥退出程式 */
gint delete_event( GtkWidget *widget, GdkEvent *event, gpointer data )
{
gtk_main_quit ();
return FALSE;
}
int main( int argc, char *argv[] )
{
GtkWidget *window;
GtkWidget *button;
GtkWidget *table;
gtk_init (&argc, &argv);
/* 建立一個新視窗 */
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
/* 設定視窗標題 */
gtk_window_set_title (GTK_WINDOW (window), "Rong Tao's Keyboard");
/* 為 delete_event 設定一個立即退出 GTK 的處理函式。 */
g_signal_connect (G_OBJECT (window), "delete_event", G_CALLBACK (delete_event), NULL);
/* 設定視窗的邊框寬度。 */
gtk_container_set_border_width (GTK_CONTAINER (window), 20);
/* 建立一個 2x2 的表 */
table = gtk_table_new (4, 20, TRUE);
/* 將表放進主視窗 */
gtk_container_add (GTK_CONTAINER (window), table);
/* 建立第一個按鈕 */
button = gtk_button_new_with_label ("Q");
/* 當這個按鈕被點選時,我們呼叫 "callback" 函式,並將一個指向"button 1"的指標作為它的引數 */
g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (callback), (gpointer) "q");
/* 將 button 1 插入表的左上象限(quadrant) */
gtk_table_attach_defaults (GTK_TABLE (table), button, 0, 2, 0, 1);
gtk_widget_show (button);
/*********************/
button = gtk_button_new_with_label ("W");
g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (callback), (gpointer) "w");
gtk_table_attach_defaults (GTK_TABLE (table), button, 2, 4, 0, 1);
gtk_widget_show (button);
/*********************/
button = gtk_button_new_with_label ("E");
g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (callback), (gpointer) "e");
gtk_table_attach_defaults (GTK_TABLE (table), button, 4, 6, 0, 1);
gtk_widget_show (button);
/*********************/
button = gtk_button_new_with_label ("R");
g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (callback), (gpointer) "r");
gtk_table_attach_defaults (GTK_TABLE (table), button, 6, 8, 0, 1);
gtk_widget_show (button);
/*********************/
button = gtk_button_new_with_label ("T");
g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (callback), (gpointer) "t");
gtk_table_attach_defaults (GTK_TABLE (table), button, 8, 10, 0, 1);
gtk_widget_show (button);
/*********************/
button = gtk_button_new_with_label ("Y");
g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (callback), (gpointer) "y");
gtk_table_attach_defaults (GTK_TABLE (table), button, 10, 12, 0, 1);
gtk_widget_show (button);
/*********************/
button = gtk_button_new_with_label ("U");
g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (callback), (gpointer) "u");
gtk_table_attach_defaults (GTK_TABLE (table), button, 12, 14, 0, 1);
gtk_widget_show (button);
/*********************/
button = gtk_button_new_with_label ("I");
g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (callback), (gpointer) "i");
gtk_table_attach_defaults (GTK_TABLE (table), button, 14, 16, 0, 1);
gtk_widget_show (button);
/*********************/
button = gtk_button_new_with_label ("O");
g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (callback), (gpointer) "o");
gtk_table_attach_defaults (GTK_TABLE (table), button, 16, 18, 0, 1);
gtk_widget_show (button);
/*********************/
button = gtk_button_new_with_label ("P");
g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (callback), (gpointer) "p");
gtk_table_attach_defaults (GTK_TABLE (table), button, 18, 20, 0, 1);
gtk_widget_show (button);
/*********************/
button = gtk_button_new_with_label ("A");
g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (callback), (gpointer) "a");
gtk_table_attach_defaults (GTK_TABLE (table), button, 1, 3, 1, 2);
gtk_widget_show (button);
/*********************/
button = gtk_button_new_with_label ("S");
g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (callback), (gpointer) "s");
gtk_table_attach_defaults (GTK_TABLE (table), button, 3, 5, 1, 2);
gtk_widget_show (button);
/*********************/
button = gtk_button_new_with_label ("D");
g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (callback), (gpointer) "d");
gtk_table_attach_defaults (GTK_TABLE (table), button, 5, 7, 1, 2);
gtk_widget_show (button);
/*********************/
button = gtk_button_new_with_label ("F");
g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (callback), (gpointer) "f");
gtk_table_attach_defaults (GTK_TABLE (table), button, 7, 9, 1, 2);
gtk_widget_show (button);
/*********************/
button = gtk_button_new_with_label ("G");
g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (callback), (gpointer) "g");
gtk_table_attach_defaults (GTK_TABLE (table), button, 9, 11, 1, 2);
gtk_widget_show (button);
/*********************/
button = gtk_button_new_with_label ("H");
g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (callback), (gpointer) "h");
gtk_table_attach_defaults (GTK_TABLE (table), button, 11, 13, 1, 2);
gtk_widget_show (button);
/*********************/
button = gtk_button_new_with_label ("J");
g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (callback), (gpointer) "j");
gtk_table_attach_defaults (GTK_TABLE (table), button, 13, 15, 1, 2);
gtk_widget_show (button);
/*********************/
button = gtk_button_new_with_label ("K");
g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (callback), (gpointer) "k");
gtk_table_attach_defaults (GTK_TABLE (table), button, 15, 17, 1, 2);
gtk_widget_show (button);
/*********************/
button = gtk_button_new_with_label ("L");
g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (callback), (gpointer) "l");
gtk_table_attach_defaults (GTK_TABLE (table), button, 17, 19, 1, 2);
gtk_widget_show (button);
/*********************/
button = gtk_button_new_with_label ("'");
g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (callback), (gpointer) "'");
gtk_table_attach_defaults (GTK_TABLE (table), button, 0, 2, 2, 3);
gtk_widget_show (button);
/*********************/
button = gtk_button_new_with_label ("Z");
g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (callback), (gpointer) "z");
gtk_table_attach_defaults (GTK_TABLE (table), button, 2, 4, 2, 3);
gtk_widget_show (button);
/*********************/
button = gtk_button_new_with_label ("X");
g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (callback), (gpointer) "x");
gtk_table_attach_defaults (GTK_TABLE (table), button, 4, 6, 2, 3);
gtk_widget_show (button);
/*********************/
button = gtk_button_new_with_label ("C");
g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (callback), (gpointer) "c");
gtk_table_attach_defaults (GTK_TABLE (table), button, 6, 8, 2, 3);
gtk_widget_show (button);
/*********************/
button = gtk_button_new_with_label ("V");
g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (callback), (gpointer) "v");
gtk_table_attach_defaults (GTK_TABLE (table), button, 8, 10, 2, 3);
gtk_widget_show (button);
/*********************/
button = gtk_button_new_with_label ("B");
g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (callback), (gpointer) "b");
gtk_table_attach_defaults (GTK_TABLE (table), button, 10, 12, 2, 3);
gtk_widget_show (button);
/*********************/
button = gtk_button_new_with_label ("N");
g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (callback), (gpointer) "n");
gtk_table_attach_defaults (GTK_TABLE (table), button, 12, 14, 2, 3);
gtk_widget_show (button);
/*********************/
button = gtk_button_new_with_label ("M");
g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (callback), (gpointer) "m");
gtk_table_attach_defaults (GTK_TABLE (table), button, 14, 16, 2, 3);
gtk_widget_show (button);
/*********************/
button = gtk_button_new_with_label (",");
g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (callback), (gpointer) ",");
gtk_table_attach_defaults (GTK_TABLE (table), button, 16, 18, 2, 3);
gtk_widget_show (button);
/*********************/
button = gtk_button_new_with_label (".");
g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (callback), (gpointer) ".");
gtk_table_attach_defaults (GTK_TABLE (table), button, 18, 20, 2, 3);
gtk_widget_show (button);
/*********************/
button = gtk_button_new_with_label ("Enter");
g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (callback), (gpointer) "\n");
gtk_table_attach_defaults (GTK_TABLE (table), button, 2, 6, 3, 4);
gtk_widget_show (button);
/*********************/
button = gtk_button_new_with_label (" ");
g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (callback), (gpointer) " ");
gtk_table_attach_defaults (GTK_TABLE (table), button, 6, 16, 3, 4);
gtk_widget_show (button);
/* 建立"Quit"按鈕 */
button = gtk_button_new_with_label ("Quit");
/* 當這個按鈕被點選時,我們呼叫 "delete_event" 函式接著程式就退出了 */
g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (delete_event), NULL);
/* 將退出按鈕插入表的下面兩個象限 */
gtk_table_attach_defaults (GTK_TABLE (table), button, 16, 19, 3, 4);
gtk_widget_show (button);
gtk_widget_show (table);
gtk_widget_show (window);
gtk_main ();
return 0;
}
06.一個簡單的畫圖draw介面
/* 繪圖軟體 brush.c */
#include <gtk/gtk.h>
static GtkWidget *window = NULL;
static GdkPixmap *pixmap = NULL;
static gboolean
scribble_configure_event (GtkWidget *widget,GdkEventConfigure *event,gpointer data)
{
if (pixmap)
g_object_unref (G_OBJECT (pixmap));
pixmap = gdk_pixmap_new (widget->window,
widget->allocation.width,
widget->allocation.height,-1);
gdk_draw_rectangle (pixmap,widget->style->white_gc,
TRUE,0,0,widget->allocation.width,
widget->allocation.height);
return TRUE;
}
static gboolean scribble_expose_event (GtkWidget *widget,GdkEventExpose *event,gpointer data)
{
gdk_draw_drawable (widget->window,
widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
pixmap,
event->area.x, event->area.y,
event->area.x, event->area.y,
event->area.width, event->area.height);
return FALSE;
}
static void draw_brush (GtkWidget *widget, gdouble x, gdouble y)
{
GdkRectangle update_rect;
update_rect.x = x - 3;
update_rect.y = y - 3;
update_rect.width = 6;
update_rect.height = 6;
gdk_draw_rectangle (pixmap,
widget->style->black_gc,
TRUE,
update_rect.x, update_rect.y,
update_rect.width, update_rect.height);
gdk_window_invalidate_rect (widget->window,
&update_rect,
FALSE);
}
static gboolean scribble_button_press_event (GtkWidget *widget,GdkEventButton *event,gpointer data)
{
if (pixmap == NULL)
return FALSE;
if (event->button == 1)
draw_brush (widget, event->x, event->y);
return TRUE;
}
static gboolean scribble_motion_notify_event (GtkWidget *widget,GdkEventMotion *event,gpointer data)
{
int x, y;
GdkModifierType state;
if (pixmap == NULL)
return FALSE;
gdk_window_get_pointer (event->window, &x, &y, &state);
if (state & GDK_BUTTON1_MASK)
draw_brush (widget, x, y);
return TRUE;
}
static gboolean checkerboard_expose (GtkWidget *da, GdkEventExpose *event,gpointer data)
{
gint i, j, xcount, ycount;
GdkGC *gc1, *gc2;
GdkColor color;
#define CHECK_SIZE 10
#define SPACING 2
gc1 = gdk_gc_new (da->window);
color.red = 30000;
color.green = 0;
color.blue = 30000;
gdk_gc_set_rgb_fg_color (gc1, &color);
gc2 = gdk_gc_new (da->window);
color.red = 65535;
color.green = 65535;
color.blue = 65535;
gdk_gc_set_rgb_fg_color (gc2, &color);
xcount = 0;
i = SPACING;
while (i < da->allocation.width)
{
j = SPACING;
ycount = xcount % 2;
while (j < da->allocation.height)
{
GdkGC *gc;
if (ycount % 2)
gc = gc1;
else
gc = gc2;
gdk_draw_rectangle (da->window, gc, TRUE,
i, j, CHECK_SIZE, CHECK_SIZE);
j += CHECK_SIZE + SPACING;
++ycount;
}
i += CHECK_SIZE + SPACING;
++xcount;
}
g_object_unref (G_OBJECT (gc1));
g_object_unref (G_OBJECT (gc2));
return TRUE;
}
int main (int argc,char* argv[])
{
GtkWidget *frame;
GtkWidget *vbox;
GtkWidget *da;
GtkWidget *label;
gtk_init(&argc,&argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "繪圖軟體");
g_signal_connect (G_OBJECT(window), "delete_event",
G_CALLBACK (gtk_main_quit), NULL);
gtk_container_set_border_width (GTK_CONTAINER (window), 10);
vbox = gtk_vbox_new (FALSE, 8);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 8);
gtk_container_add (GTK_CONTAINER (window), vbox);
label = gtk_label_new (NULL);
gtk_label_set_markup (GTK_LABEL (label),"<u>繪圖區域</u>");
gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
gtk_box_pack_start (GTK_BOX (vbox), frame, TRUE, TRUE, 0);
da = gtk_drawing_area_new ();
gtk_widget_set_size_request (da, 100, 100);
gtk_container_add (GTK_CONTAINER (frame), da);
g_signal_connect (da, "expose_event",
G_CALLBACK (scribble_expose_event), NULL);
g_signal_connect (da, "configure_event",
G_CALLBACK (scribble_configure_event), NULL);
g_signal_connect (da, "motion_notify_event",
G_CALLBACK (scribble_motion_notify_event), NULL);
g_signal_connect (da, "button_press_event",
G_CALLBACK (scribble_button_press_event), NULL);
gtk_widget_set_events (da, gtk_widget_get_events (da)
| GDK_LEAVE_NOTIFY_MASK
| GDK_BUTTON_PRESS_MASK
| GDK_POINTER_MOTION_MASK
| GDK_POINTER_MOTION_HINT_MASK);
gtk_widget_show_all (window);
gtk_main();
return FALSE;
}
07.帶圖片的按鈕
/* 帶影象的按鈕 button.c */
#include <gtk/gtk.h>
void on_button_clicked (GtkWidget* button,gpointer data)
{
//g_print("按鈕 %s ",(gchar*)data);
g_print("Button %s is pressed.\n",(gchar*)data);
//g_print("被按了一下. \n");
}
//建立自己按鈕的函式
GtkWidget* create_button1 (void)
{
GtkWidget* box;
GtkWidget* image;
GtkWidget* label;
GtkWidget* button;
char* title = "檔案家";
image = gtk_image_new_from_file("dir2.jpg");
label = gtk_label_new(title);
box = gtk_vbox_new(FALSE,2);
gtk_container_set_border_width(GTK_CONTAINER(box),5);
gtk_box_pack_start(GTK_BOX(box),image,FALSE,FALSE,3);
gtk_box_pack_start(GTK_BOX(box),label,FALSE,FALSE,3);
gtk_widget_show(image);
gtk_widget_show(label);
button = gtk_button_new();
gtk_container_add(GTK_CONTAINER(button),box);
gtk_widget_show(box);
return button ;
}
GtkWidget* create_button2 (void)
{
GtkWidget* box;
GtkWidget* image;
GtkWidget* label;
GtkWidget* button;
char* title = "蝙蝠俠";
image = gtk_image_new_from_file("batman.jpg");
label = gtk_label_new(title);
box = gtk_hbox_new(FALSE,2);
gtk_container_set_border_width(GTK_CONTAINER(box),5);
gtk_box_pack_start(GTK_BOX(box),image,FALSE,FALSE,3);
gtk_box_pack_start(GTK_BOX(box),label,FALSE,FALSE,3);
gtk_widget_show(image);
gtk_widget_show(label);
button = gtk_button_new();
gtk_container_add(GTK_CONTAINER(button),box);
gtk_widget_show(box);
return button ;
}
//主函式
int main (int argc, char *argv[])
{
GtkWidget* window;
GtkWidget* box;
GtkWidget* button1;
GtkWidget* button2;
GtkWidget* button3;
GtkWidget* button4;
gchar* title = "帶影象和快捷鍵的按鈕";
gchar* b1 = "Red apple";//"紅蘋果"
gchar* b2 = "Small mushroom";//"小蘑菇"
gchar* b3 = "Short key";//"快捷鍵"
gchar* b4 = "OK";//"確認"
gtk_init(&argc,&argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window),title);
gtk_container_set_border_width(GTK_CONTAINER(window),20);
g_signal_connect(G_OBJECT(window),"destroy",G_CALLBACK(gtk_main_quit),NULL);
box = gtk_hbox_new(FALSE,0);
gtk_container_add(GTK_CONTAINER(window),box);
button1 = create_button1();
g_signal_connect(G_OBJECT(button1),"clicked",
G_CALLBACK(on_button_clicked),(gpointer)b1);
gtk_box_pack_start(GTK_BOX(box),button1,FALSE,FALSE,5);
button2 = create_button2();
g_signal_connect(G_OBJECT(button2),"clicked",
G_CALLBACK(on_button_clicked),(gpointer)b2);
gtk_box_pack_start(GTK_BOX(box),button2,FALSE,FALSE,5);
button3 = gtk_button_new_with_mnemonic("快捷鍵(_H)");
g_signal_connect(G_OBJECT(button3),"clicked",
G_CALLBACK(on_button_clicked),(gpointer)b3);
gtk_box_pack_start(GTK_BOX(box),button3,FALSE,FALSE,5);
button4 = gtk_button_new_from_stock(GTK_STOCK_OK);
g_signal_connect(G_OBJECT(button4),"clicked",
G_CALLBACK(on_button_clicked),(gpointer)b4);
gtk_box_pack_start(GTK_BOX(box),button4,FALSE,FALSE,5);
gtk_widget_show_all(window);
gtk_main();
return FALSE ;
}
08.多選按鈕check button
/* 多項選擇視窗 checkbutton.c */
#include <gtk/gtk.h>
gboolean isbold = FALSE ;
gboolean isitli = FALSE ;
gboolean isuline = FALSE ;
gboolean iscolor = FALSE ;
void on_check_clicked (GtkWidget* check,gint data)
{
switch((int)data)
{
case 1:
isbold = !isbold;
break;
case 2:
isitli = !isitli;
break;
case 3:
isuline = !isuline;
break;
case 4:
iscolor = !iscolor;
break;
}
}
void on_button_clicked (GtkWidget *button,gpointer data)
{
g_print("字型配置為:");
if(isbold)
g_print("粗體 ");
if(isitli)
g_print("斜體 ");
if(isuline)
g_print("下劃線 ");
if(iscolor)
g_print("彩色 ");
if( !isbold && !iscolor && !isuline && !isitli )
g_print("正常,無任何選項");
g_print("\n");
}
//主函式
int main (int argc, char *argv[])
{
GtkWidget* window;
GtkWidget* frame;
GtkWidget* box;
GtkWidget* button;
GtkWidget* box1;
GtkWidget* check1;
GtkWidget* check2;
GtkWidget* check3;
GtkWidget* check4;
char* title = "多項選擇視窗";
gtk_init(&argc,&argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window),title);
gtk_container_set_border_width(GTK_CONTAINER(window),20);
g_signal_connect(G_OBJECT(window),"destroy",
G_CALLBACK(gtk_main_quit),NULL);
box = gtk_vbox_new(FALSE,0);
gtk_container_add(GTK_CONTAINER(window),box);
frame = gtk_frame_new("字型選項:");
gtk_box_pack_start(GTK_BOX(box),frame,FALSE,FALSE,5);
box1 = gtk_vbox_new(FALSE,0);
gtk_container_add(GTK_CONTAINER(frame),box1);
gtk_container_set_border_width(GTK_CONTAINER(box1),10);
gtk_widget_show(box);
check1 = gtk_check_button_new_with_label(" 粗體 ");
g_signal_connect(G_OBJECT(check1),"released",
G_CALLBACK(on_check_clicked),(gpointer)1);
gtk_box_pack_start(GTK_BOX(box1),check1,FALSE,FALSE,3);
check2 = gtk_check_button_new_with_label(" 斜體 ");
g_signal_connect(G_OBJECT(check2),"released",
G_CALLBACK(on_check_clicked),(gpointer)2);
gtk_box_pack_start(GTK_BOX(box1),check2,FALSE,FALSE,3);
check3 = gtk_check_button_new_with_label(" 下劃線 ");
g_signal_connect(G_OBJECT(check3),"released",
G_CALLBACK(on_check_clicked),(gpointer)3);
gtk_box_pack_start(GTK_BOX(box1),check3,FALSE,FALSE,3);
check4 = gtk_check_button_new_with_label(" 彩色 ");
g_signal_connect(G_OBJECT(check4),"released",
G_CALLBACK(on_check_clicked),(gpointer)4);
gtk_box_pack_start(GTK_BOX(box1),check4,FALSE,FALSE,3);
button = gtk_button_new_from_stock(GTK_STOCK_OK);
g_signal_connect(G_OBJECT(button),"clicked",
G_CALLBACK(on_button_clicked),NULL);
g_signal_connect_swapped(G_OBJECT(button),"clicked",
G_CALLBACK(gtk_widget_destroy),window);
gtk_box_pack_start(GTK_BOX(box),button,FALSE,FALSE,5);
gtk_widget_show_all(window);
gtk_main();
return FALSE ;
}
09.單選按鈕radio button
這裡給出兩個例子
#include <glib.h>
#include <gtk/gtk.h>
gint close_application( GtkWidget *widget, GdkEvent *event, gpointer data )
{
gtk_main_quit ();
return FALSE;
}
int main( int argc, char *argv[] )
{
GtkWidget *window = NULL;
GtkWidget *box1;
GtkWidget *box2;
GtkWidget *button;
GtkWidget *separator;
GSList *group;
gtk_init (&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
g_signal_connect (G_OBJECT (window), "delete_event",
G_CALLBACK (close_application), NULL);
gtk_window_set_title (GTK_WINDOW (window), "radio buttons");
gtk_container_set_border_width (GTK_CONTAINER (window), 0);
box1 = gtk_vbox_new (FALSE, 0);
gtk_container_add (GTK_CONTAINER (window), box1);
gtk_widget_show (box1);
box2 = gtk_hbox_new (FALSE, 10);
gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
gtk_widget_show (box2);
button = gtk_radio_button_new_with_label (NULL, "Leonvel");
gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
gtk_widget_show (button);
group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (button));
button = gtk_radio_button_new_with_label (group, "Rong");
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
gtk_widget_show (button);
button = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (button),
"Tao");
gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
gtk_widget_show (button);
separator = gtk_hseparator_new ();
gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
gtk_widget_show (separator);
box2 = gtk_vbox_new (FALSE, 10);
gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
gtk_widget_show (box2);
button = gtk_button_new_with_label ("close");
g_signal_connect_swapped (G_OBJECT (button), "clicked",
G_CALLBACK (close_application), window);
gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
gtk_widget_grab_default (button);
gtk_widget_show (button);
gtk_widget_show (window);
gtk_main ();
return 0;
}
第二個例子
/* 單項選擇視窗 radiobutton.c */
#include <gtk/gtk.h>
static gchar* red = " 紅色 " ;
static gchar* green = " 綠色 " ;
static gchar* yellow = " 黃色 " ;
static gchar* blue = " 藍色 " ;
void on_radio_clicked (GtkWidget* radio,gint data)
{
g_print("你選擇的顏色是:");
switch((int)data)
{
case 1:
g_print("%s",red); break;
case 2:
g_print("%s",green); break;
case 3:
g_print("%s",yellow); break;
case 4:
g_print("%s",blue); break;
}
g_print("\n");
}
//主函式
int main (int argc, char *argv[])
{
GtkWidget* window;
GtkWidget* frame;
GtkWidget* box;
GtkWidget* box1;
GtkWidget* button1;
GtkWidget* radio1;
GtkWidget* radio2;
GtkWidget* radio3;
GtkWidget* radio4;
GSList* group;
gchar* title = "單項選擇視窗" ;
gtk_init(&argc,&argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window),title);
gtk_container_set_border_width(GTK_CONTAINER(window),10);
g_signal_connect(G_OBJECT(window),"destroy",
G_CALLBACK(gtk_main_quit),NULL);
box = gtk_vbox_new(FALSE,0);
gtk_container_add(GTK_CONTAINER(window),box);
frame = gtk_frame_new("請選擇一種顏色:");
gtk_frame_set_shadow_type(GTK_FRAME(frame),GTK_SHADOW_ETCHED_OUT);
gtk_box_pack_start(GTK_BOX(box),frame,FALSE,FALSE,5);
box1 = gtk_hbox_new(FALSE,10);
gtk_container_set_border_width(GTK_CONTAINER(box1),10);
gtk_container_add(GTK_CONTAINER(frame),box1);
radio1 = gtk_radio_button_new_with_label(NULL,red);//紅色
g_signal_connect(G_OBJECT(radio1),"released",
G_CALLBACK(on_radio_clicked),(gpointer)1);
gtk_box_pack_start(GTK_BOX(box1),radio1,FALSE,FALSE,5);
//建立多選按鈕組
group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(radio1));
radio2 = gtk_radio_button_new_with_label(group,green);//綠色
g_signal_connect(G_OBJECT(radio2),"released",
G_CALLBACK(on_radio_clicked),(gpointer)2);
gtk_box_pack_start(GTK_BOX(box1),radio2,FALSE,FALSE,5);
group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(radio2));
radio3 = gtk_radio_button_new_with_label(group,yellow);//黃色
g_signal_connect(G_OBJECT(radio3),"released",
G_CALLBACK(on_radio_clicked),(gpointer)3);
gtk_box_pack_start(GTK_BOX(box1),radio3,FALSE,FALSE,5);
group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(radio3));
radio4 = gtk_radio_button_new_with_label(group,blue);//藍色
g_signal_connect(G_OBJECT(radio4),"released",
G_CALLBACK(on_radio_clicked),(gpointer)4);
gtk_box_pack_start(GTK_BOX(box1),radio4,FALSE,FALSE,5);
button1 = gtk_button_new_from_stock(GTK_STOCK_OK);
g_signal_connect(G_OBJECT(button1),"clicked",
G_CALLBACK(gtk_main_quit),NULL);
gtk_box_pack_start(GTK_BOX(box),button1,FALSE,FALSE,5);
gtk_widget_show_all(window);
gtk_main();
return FALSE ;
}
10.控制條scrollbar
#include <gtk/gtk.h>
GtkWidget *hscale, *vscale;
void cb_pos_menu_select( GtkWidget *item, GtkPositionType pos )
{
/* 設定兩個比例構件的比例值的顯示位置 */
gtk_scale_set_value_pos (GTK_SCALE (hscale), pos);
gtk_scale_set_value_pos (GTK_SCALE (vscale), pos);
}
void cb_update_menu_select( GtkWidget *item, GtkUpdateType policy )
{
/* 設定兩個比例構件的更新方式 */
gtk_range_set_update_policy (GTK_RANGE (hscale), policy);
gtk_range_set_update_policy (GTK_RANGE (vscale), policy);
}
void cb_digits_scale( GtkAdjustment *adj )
{
/* 設定 adj->value 圓整的小數位數 */
gtk_scale_set_digits (GTK_SCALE (hscale), (gint) adj->value);
gtk_scale_set_digits (GTK_SCALE (vscale), (gint) adj->value);
}
void cb_page_size( GtkAdjustment *get, GtkAdjustment *set )
{
/* 將示例調整物件的 page size 和 page increment size 設定
* 為"Page Size"比例構件指定的值 */
set->page_size = get->value;
set->page_increment = get->value;
/* 設定調整物件的值並使它引發一個 "changed" 訊號,以重新配置所有
* 已經連線到這個調整物件的構件。 */
gtk_adjustment_set_value (set, CLAMP (set->value,
set->lower, (set->upper - set->page_size)));
}
void cb_draw_value( GtkToggleButton *button )
{
/* 根據複選按鈕的狀態設定在比例構件上是否顯示比例值 */
gtk_scale_set_draw_value (GTK_SCALE (hscale), button->active);
gtk_scale_set_draw_value (GTK_SCALE (vscale), button->active);
}
/* 方便的函式 */
GtkWidget *make_menu_item (gchar *name, GCallback callback, gpointer data)
{
GtkWidget *item;
item = gtk_menu_item_new_with_label (name);
g_signal_connect (G_OBJECT (item), "activate", callback, data);
gtk_widget_show (item);
return item;
}
void scale_set_default_values( GtkScale *scale )
{
gtk_range_set_update_policy (GTK_RANGE (scale),
GTK_UPDATE_CONTINUOUS);
gtk_scale_set_digits (scale, 1);
gtk_scale_set_value_pos (scale, GTK_POS_TOP);
gtk_scale_set_draw_value (scale, TRUE);
}
/* 建立示例視窗 */
void create_range_controls( void )
{
GtkWidget *window;
GtkWidget *box1, *box2, *box3;
GtkWidget *button;
GtkWidget *scrollbar;
GtkWidget *separator;
GtkWidget *opt, *menu, *item;
GtkWidget *label;
GtkWidget *scale;
GtkObject *adj1, *adj2;
/* 標準的建立視窗程式碼 */
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (gtk_main_quit), NULL);
gtk_window_set_title (GTK_WINDOW (window), "RT's range controls");
box1 = gtk_vbox_new (FALSE, 0);
gtk_container_add (GTK_CONTAINER (window), box1);
gtk_widget_show (box1);
box2 = gtk_hbox_new (FALSE, 10);
gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
gtk_widget_show (box2);
/* value, lower, upper, step_increment, page_increment, page_size */
/* 注意,page_size 值只對滾動條構件有區別,並且,你實際上能取得的最高值
* 是(upper - page_size)。 */
adj1 = gtk_adjustment_new (0.0, 0.0, 101.0, 0.1, 1.0, 1.0);
vscale = gtk_vscale_new (GTK_ADJUSTMENT (adj1));
scale_set_default_values (GTK_SCALE (vscale));
gtk_box_pack_start (GTK_BOX (box2), vscale, TRUE, TRUE, 0);
gtk_widget_show (vscale);
box3 = gtk_vbox_new (FALSE, 10);
gtk_box_pack_start (GTK_BOX (box2), box3, TRUE, TRUE, 0);
gtk_widget_show (box3);
/* 重新使用同一個調整物件 */
hscale = gtk_hscale_new (GTK_ADJUSTMENT (adj1));
gtk_widget_set_size_request (GTK_WIDGET (hscale), 200, -1);
scale_set_default_values (GTK_SCALE (hscale));
gtk_box_pack_start (GTK_BOX (box3), hscale, TRUE, TRUE, 0);
gtk_widget_show (hscale);
/* 再次重用同一個調整物件 */
scrollbar = gtk_hscrollbar_new (GTK_ADJUSTMENT (adj1));
/* 注意,這導致當滾動條移動時,比例構件總是連續更新 */
gtk_range_set_update_policy (GTK_RANGE (scrollbar),
GTK_UPDATE_CONTINUOUS);
gtk_box_pack_start (GTK_BOX (box3), scrollbar, TRUE, TRUE, 0);
gtk_widget_show (scrollbar);
box2 = gtk_hbox_new (FALSE, 10);
gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
gtk_widget_show (box2);
/* 用一個複選按鈕控制是否顯示比例構件的值 */
button = gtk_check_button_new_with_label("Display value on scale widgets");
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
g_signal_connect (G_OBJECT (button), "toggled",
G_CALLBACK (cb_draw_value), NULL);
gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
gtk_widget_show (button);
box2 = gtk_hbox_new (FALSE, 10);
gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
/* 用一個選項選單以改變顯示值的位置 */
label = gtk_label_new ("Scale Value Position:");
gtk_box_pack_start (GTK_BOX (box2), label, FALSE, FALSE, 0);
gtk_widget_show (label);
opt = gtk_option_menu_new ();
menu = gtk_menu_new ();
item = make_menu_item ("Top", G_CALLBACK (cb_pos_menu_select),
GINT_TO_POINTER (GTK_POS_TOP));
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
item = make_menu_item ("Bottom", G_CALLBACK (cb_pos_menu_select),
GINT_TO_POINTER (GTK_POS_BOTTOM));
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
item = make_menu_item ("Left", G_CALLBACK (cb_pos_menu_select),
GINT_TO_POINTER (GTK_POS_LEFT));
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
item = make_menu_item ("Right", G_CALLBACK (cb_pos_menu_select),
GINT_TO_POINTER (GTK_POS_RIGHT));
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
gtk_option_menu_set_menu (GTK_OPTION_MENU (opt), menu);
gtk_box_pack_start (GTK_BOX (box2), opt, TRUE, TRUE, 0);
gtk_widget_show (opt);
gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
gtk_widget_show (box2);
box2 = gtk_hbox_new (FALSE, 10);
gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
/* 另一個選項選單,這裡是用於設定比例構件的更新方式 */
label = gtk_label_new ("Scale Update Policy:");
gtk_box_pack_start (GTK_BOX (box2), label, FALSE, FALSE, 0);
gtk_widget_show (label);
opt = gtk_option_menu_new ();
menu = gtk_menu_new ();
item = make_menu_item ("Continuous", G_CALLBACK (cb_update_menu_select),
GINT_TO_POINTER (GTK_UPDATE_CONTINUOUS));
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
item = make_menu_item ("Discontinuous", G_CALLBACK (cb_update_menu_select),
GINT_TO_POINTER (GTK_UPDATE_DISCONTINUOUS));
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
item = make_menu_item ("Delayed", G_CALLBACK (cb_update_menu_select),
GINT_TO_POINTER (GTK_UPDATE_DELAYED));
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
gtk_option_menu_set_menu (GTK_OPTION_MENU (opt), menu);
gtk_box_pack_start (GTK_BOX (box2), opt, TRUE, TRUE, 0);
gtk_widget_show (opt);
gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
gtk_widget_show (box2);
box2 = gtk_hbox_new (FALSE, 10);
gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
/* 一個水平比例構件,用於調整示例比例構件的顯示小數位數。 */
label = gtk_label_new ("Scale Digits:");
gtk_box_pack_start (GTK_BOX (box2), label, FALSE, FALSE, 0);
gtk_widget_show (label);
adj2 = gtk_adjustment_new (1.0, 0.0, 5.0, 1.0, 1.0, 0.0);
g_signal_connect (G_OBJECT (adj2), "value_changed",
G_CALLBACK (cb_digits_scale), NULL);
scale = gtk_hscale_new (GTK_ADJUSTMENT (adj2));
gtk_scale_set_digits (GTK_SCALE (scale), 0);
gtk_box_pack_start (GTK_BOX (box2), scale, TRUE, TRUE, 0);
gtk_widget_show (scale);
gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
gtk_widget_show (box2);
box2 = gtk_hbox_new (FALSE, 10);
gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
/* 以及,最後一個水平比例構件用於調整滾動條的 page size。 */
label = gtk_label_new ("Scrollbar Page Size:");
gtk_box_pack_start (GTK_BOX (box2), label, FALSE, FALSE, 0);
gtk_widget_show (label);
adj2 = gtk_adjustment_new (1.0, 1.0, 101.0, 1.0, 1.0, 0.0);
g_signal_connect (G_OBJECT (adj2), "value_changed",
G_CALLBACK (cb_page_size), adj1);
scale =