### 標簽 Labels
標簽(Labels)是 GTK 中最常用的構件,實際上它很簡單。因為沒有相關聯的 X 窗口,標簽不能引發信號。如果需要獲取或引發信號,可以將它放在一個事件盒中,或放在按鈕構件里面。
下面是Labels的使用一個實例,點擊按鈕,可以打印原來標簽的內容,并設置新的內容,具體代碼如下:?
~~~
/*File:label.c
*Date:2013-12-13
*Author:sjin
*Mail:413977243@qq.com
*/
#include<gtk/gtk.h>
GtkWidget *label1;
void callBack(GtkWidget *widget,gpointer data)
{
printf("label1 = %s\n",gtk_label_get_text(GTK_LABEL(label1)));
gtk_label_set_text(GTK_LABEL(label1),(char*)data);
sleep(1);
gtk_main_quit();
}
int main(int argc, char*argv[])
{
GtkWidget *window;
GtkWidget *box;
GtkWidget *label2;
GtkWidget *label3;
GtkWidget *label4;
GtkWidget *frame1;
GtkWidget *frame2;
GtkWidget *frame3;
GtkWidget *frame4;
GtkWidget *button;
gchar *title ;
//初始化GTK
gtk_init(&argc,&argv);
//創建最上層主窗口
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
//連接信號"delete_event",使得窗口關閉時發生
g_signal_connect(G_OBJECT(window),"delete_event",G_CALLBACK(gtk_main_quit),NULL);
//設置窗口標題
gtk_window_set_title(GTK_WINDOW(window),"多種樣式的標簽");
//設定窗口的默認寬高
//gtk_window_set_default_size(GTK_WINDOW(window),200,300);
//設定窗口的位置,讓窗口總在最前端
gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);
//設定容器邊框的寬度
gtk_container_set_border_width(GTK_CONTAINER(window),20);
//創建盒子
box = gtk_vbox_new(FALSE,0);
gtk_container_add(GTK_CONTAINER(window),box);
//創建框架1
frame1 = gtk_frame_new("標簽一");
label1 = gtk_label_new("這是第一個標簽,居左邊的。This is the first label.");
gtk_container_add(GTK_CONTAINER(frame1),label1);
/*void gtk_label_set_justify(GtkLabel *label, GtkJustification jtype);
* jtype 值:GTK_JUSTIFY_LEFT :左對齊
* GTK_JUSTIFY_RIGHT:右對齊
* GTK_JUSTIFY_CENTER:居中對齊(默認 )
* GTK_JUSTIFY_FILL:充滿
*/
gtk_label_set_justify(GTK_LABEL(label1),GTK_JUSTIFY_LEFT);
gtk_box_pack_start(GTK_BOX(box),frame1,FALSE,FALSE,5);
frame2 = gtk_frame_new("標簽二");
label2 = gtk_label_new("這是第二個標簽,它是多行的。\n這還是第二個標簽的內容,它是居右邊的。");
gtk_container_add(GTK_CONTAINER(frame2),label2);
gtk_label_set_justify(GTK_LABEL(label2),GTK_JUSTIFY_RIGHT);
//設置下劃線
gtk_label_set_pattern(GTK_LABEL(label2),"__ __ __ ");
gtk_box_pack_start(GTK_BOX(box),frame2,FALSE,FALSE,5);
frame3 = gtk_frame_new("標簽三");
label3 = gtk_label_new(NULL);
//標記語言形式
title = "<span foreground=\"red\"><big><i>這是第三個標簽。\n它被格式化成紅色了,并且字體也大了。</i></big></span>";
gtk_container_add(GTK_CONTAINER(frame3),label3);
gtk_label_set_markup(GTK_LABEL(label3),title);
gtk_box_pack_start(GTK_BOX(box),frame3,FALSE,FALSE,5);
frame4 = gtk_frame_new("標簽四");
label4 = gtk_label_new("這也是一個多行標簽,它的換行方式和上一個有所不同,主要是編輯手段不一樣了,請仔細查看一下源碼就會明白怎么回事了。");
gtk_label_set_justify(GTK_LABEL(label1),GTK_JUSTIFY_LEFT);
//自動換行函數
gtk_label_set_line_wrap(GTK_LABEL(label4),TRUE);
gtk_container_add(GTK_CONTAINER(frame4),label4);
gtk_box_pack_start(GTK_BOX(box),frame4,FALSE,FALSE,5);
button = gtk_button_new_with_label("set label1");
gtk_box_pack_start(GTK_BOX(box),button,FALSE,FALSE,5);
g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(callBack),"set label1 111");
gtk_container_add(GTK_CONTAINER(window),button);
gtk_widget_show(button);
gtk_widget_show_all(window);
gtk_main();
return FALSE;
}
~~~
運行結果:

### 箭頭 Arrows
箭頭構件(Arrow widget)畫一個箭頭,面向幾種不同的方向,并有幾種不同的風格。在許多應用程序中,常用于創建帶箭頭的按鈕。和標簽構件一樣,它不能引發信號。下面是一個簡單的示例:
~~~
/*File:arrow.c
*Date:2013-12-15
*Author:sjin
*Mail:413977243@qq.com
* */
#include<gtk/gtk.h>
//創建自己按鈕的函數
GtkWidget * create_arrow_button(GtkArrowType arrowtype, GtkShadowType shadowtype )
{
GtkWidget *button;
GtkWidget *arrow;
button = gtk_button_new();
/*void gtk_arrow_new(GtkArrowType arrow_type,GtkShadowType shadow_type);
* 創建箭頭,
* arrow_type:箭頭方向;
* GTK_ARROW_UP:向上
* GTK_ARROW_DOWN:向下
* GTK_ARROW_LEFT:向左
* GTK_ARROW_RIGHT:向右
* shadow_type:箭頭陰影類型
* GTK_SHADOW_IN:
* GTK_SHADOW_OUT():
* GTK_SHADOW_ETCHED_IN:
* GTK_SHADOW_ETCHED_OUT:
*
*/
arrow = gtk_arrow_new(arrowtype,shadowtype);
gtk_container_add(GTK_CONTAINER(button),arrow);
gtk_widget_show(arrow);
return button;
}
void callBack(GtkWidget *widget,gchar *data)
{
printf("### %s is press\n",(char *)data);
}
//主函數
int main(int argc, char*argv[])
{
GtkWidget *window;
GtkWidget *box;
GtkWidget *arrow1;
GtkWidget *arrow2;
GtkWidget *arrow3;
GtkWidget *arrow4;
gchar *title = "方向按鈕";
//初始化GTK
gtk_init(&argc,&argv);
//創建最上層主窗口
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
//連接信號"delete_event",使得窗口關閉時發生
g_signal_connect(G_OBJECT(window),"delete_event",G_CALLBACK(gtk_main_quit),NULL);
//設置窗口標題
gtk_window_set_title(GTK_WINDOW(window),title);
//設定窗口的默認寬高
//gtk_window_set_default_size(GTK_WINDOW(window),200,300);
//設定窗口的位置,讓窗口總在最前端
gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);
//設定容器邊框的寬度
gtk_container_set_border_width(GTK_CONTAINER(window),20);
//創建盒子
box = gtk_hbox_new(FALSE,0);
gtk_container_add(GTK_CONTAINER(window),box);
gtk_widget_show(box);
//創建帶箭頭的按鈕,調用自定義的函數
arrow1 = create_arrow_button(GTK_ARROW_LEFT,GTK_SHADOW_IN);
g_signal_connect(G_OBJECT(arrow1),"clicked",G_CALLBACK(callBack),"向左");
gtk_box_pack_start(GTK_BOX(box),arrow1,FALSE,FALSE,13);
gtk_widget_show(arrow1);
arrow2 = create_arrow_button(GTK_ARROW_UP,GTK_SHADOW_OUT);
g_signal_connect(G_OBJECT(arrow2),"clicked",G_CALLBACK(callBack),"向上");
gtk_box_pack_start(GTK_BOX(box),arrow2,FALSE,FALSE,13);
gtk_widget_show(arrow2);
arrow3 = create_arrow_button(GTK_ARROW_DOWN,GTK_SHADOW_ETCHED_IN);
g_signal_connect(G_OBJECT(arrow3),"clicked",G_CALLBACK(callBack),"向下");
gtk_box_pack_start(GTK_BOX(box),arrow3,FALSE,FALSE,13);
gtk_widget_show(arrow3);
arrow4 = create_arrow_button(GTK_ARROW_RIGHT,GTK_SHADOW_ETCHED_OUT);
g_signal_connect(G_OBJECT(arrow4),"clicked",G_CALLBACK(callBack),"向右");
gtk_box_pack_start(GTK_BOX(box),arrow4,FALSE,FALSE,13);
gtk_widget_show(arrow4);
gtk_widget_show(window);
gtk_main();
return FALSE;
}
~~~

### Tooltips:
工具提示對象(Tooltips)就是當鼠標指針移到按鈕或其它構件上并停留幾秒時,彈出的文本串。 工具提示對象很容易使用。具體看下面的示例。
~~~
/*File:tooltip.c
*Date:2013-12-15
*Author:sjin
*Mail:413977243@qq.com
*/
#include <gtk/gtk.h>
GtkTooltips *tooltips;
int ch = 0;
void callback(GtkWidget *widget,gpointer data)
{
//禁用已經激活的工具提示
if(ch){
gtk_tooltips_disable(tooltips);
printf("0000\n");
ch = 0;
}else{
ch = 1;
printf("1111\n");
gtk_tooltips_enable(tooltips);
}
}
int main(int argc, char*argv[])
{
GtkWidget *window;
GtkWidget *button;
//初始化GTK
gtk_init(&argc,&argv);
//創建最上層主窗口
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
//連接信號"delete_event",使得窗口關閉時發生
g_signal_connect(G_OBJECT(window),"delete_event",G_CALLBACK(gtk_main_quit),NULL);
//設置窗口標題
gtk_window_set_title(GTK_WINDOW(window),"工具提示對象");
//設定窗口的默認寬高
//gtk_window_set_default_size(GTK_WINDOW(window),200,300);
//設定窗口的位置,讓窗口總在最前端
gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);
//設定容器邊框的寬度
gtk_container_set_border_width(GTK_CONTAINER(window),20);
//創建按鈕
button = gtk_button_new_with_label("關閉工具提示");
gtk_container_add(GTK_CONTAINER(window),button);
g_signal_connect(G_OBJECT(button),"clicked",G_CALLBACK(callback),NULL);
gtk_widget_show(button);
//創建工具提示
tooltips = gtk_tooltips_new();
gtk_tooltips_set_tip(tooltips,button,"這是一個工具提示按鈕",NULL);
gtk_tooltips_disable(tooltips);
gtk_widget_show_all(window);
gtk_main();
return FALSE;
}
~~~
### 進度條 Progress Bars
進度條用于顯示正在進行的操作的狀態。
~~~
#include <gtk/gtk.h>
typedef struct _ProgressData {
GtkWidget *window;
GtkWidget *pbar;
int timer;
gboolean activity_mode;
}ProgressData;
/* 更新進度條,這樣就能夠看到進度條的移動 */
gint progress_timeout( gpointer data )
{
ProgressData *pdata =(ProgressData *)data;
gdouble new_val;
if (pdata->activity_mode)
gtk_progress_bar_pulse (GTK_PROGRESS_BAR (pdata->pbar));
else
{
/* 使用在調整對象中設置的取值范圍計算進度條的值 */
new_val =gtk_progress_bar_get_fraction (GTK_PROGRESS_BAR (pdata->pbar)) + 0.01;
if (new_val >1.0)
new_val =0.0;
/* 設置進度條的新值 */
gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (pdata->pbar), new_val);
}
/* 這是一個 timeout 函數,返回 TRUE,這樣它就能夠繼續被調用 */
return TRUE;
}
/* 回調函數,切換在進度條你的滑槽上的文本顯示 */
void toggle_show_text( GtkWidget *widget,
ProgressData *pdata )
{
const gchar *text;
text =gtk_progress_bar_get_text (GTK_PROGRESS_BAR (pdata->pbar));
if (text && *text)
gtk_progress_bar_set_text (GTK_PROGRESS_BAR (pdata->pbar), "");
else
gtk_progress_bar_set_text (GTK_PROGRESS_BAR (pdata->pbar), "some text");
}
/* 回調函數,切換進度條的活動模式 */
void toggle_activity_mode( GtkWidget *widget,
ProgressData *pdata )
{
pdata->activity_mode = !pdata->activity_mode;
if (pdata->activity_mode)
gtk_progress_bar_pulse (GTK_PROGRESS_BAR (pdata->pbar));
else
/**/
gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (pdata->pbar), 0.0);
}
/* 回調函數,切換進度條的移動方向 */
void toggle_orientation( GtkWidget *widget,
ProgressData *pdata )
{
/*獲得滾動條的移動方向*/
switch (gtk_progress_bar_get_orientation (GTK_PROGRESS_BAR (pdata->pbar))) {
case GTK_PROGRESS_LEFT_TO_RIGHT:
/*設置滾動條移動方向*/
gtk_progress_bar_set_orientation (GTK_PROGRESS_BAR (pdata->pbar),
GTK_PROGRESS_RIGHT_TO_LEFT);
break;
case GTK_PROGRESS_RIGHT_TO_LEFT:
gtk_progress_bar_set_orientation (GTK_PROGRESS_BAR (pdata->pbar),
GTK_PROGRESS_LEFT_TO_RIGHT);
break;
default:
break;
// 什么也不做
}
}
/* 清除分配的內存,刪除定時器(timer) */
void destroy_progress( GtkWidget *widget,ProgressData *pdata)
{
gtk_timeout_remove (pdata->timer);
pdata->timer =0;
pdata->window =NULL;
g_free (pdata);
gtk_main_quit ();
}
int main( int argc,char *argv[])
{
ProgressData *pdata;
GtkWidget *align;
GtkWidget *separator;
GtkWidget *table;
GtkWidget *button;
GtkWidget *check;
GtkWidget *vbox;
gtk_init (&argc, &argv);
/* 為傳遞到回調函數中的數據分配內存 */
pdata =g_malloc (sizeof (ProgressData));
pdata->window =gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_resizable (GTK_WINDOW (pdata->window), TRUE);
g_signal_connect (G_OBJECT (pdata->window), "destroy",G_CALLBACK (destroy_progress),pdata);
gtk_window_set_title (GTK_WINDOW (pdata->window), "進度條練習");
gtk_container_set_border_width (GTK_CONTAINER (pdata->window), 0);
vbox =gtk_vbox_new (FALSE, 5);
gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
gtk_container_add (GTK_CONTAINER (pdata->window), vbox);
gtk_widget_show (vbox);
/* 創建一個居中對齊的對象 */
align =gtk_alignment_new (0.5, 0.5, 0, 0);
gtk_box_pack_start (GTK_BOX(vbox), align, FALSE, FALSE, 5);
gtk_widget_show (align);
/* 創建進度條 */
pdata->pbar =gtk_progress_bar_new ();
gtk_container_add (GTK_CONTAINER (align), pdata->pbar);
gtk_widget_show (pdata->pbar);
/* 加一個定時器(timer),以更新進度條的值 */
pdata->timer =gtk_timeout_add (100, progress_timeout, pdata);
separator =gtk_hseparator_new ();
gtk_box_pack_start (GTK_BOX(vbox), separator, FALSE, FALSE, 0);
gtk_widget_show (separator);
/* 行數、列數、同質性(homogeneous) */
table =gtk_table_new (2, 2, FALSE);
gtk_box_pack_start (GTK_BOX(vbox), table, FALSE, TRUE, 0);
gtk_widget_show (table);
/* 添加一個復選按鈕,以選擇是否顯示在滑槽里的文本 */
check =gtk_check_button_new_with_label ("Show text");
gtk_table_attach (GTK_TABLE (table), check, 0, 1, 0, 1,GTK_EXPAND |GTK_FILL, GTK_EXPAND |GTK_FILL,5, 5);
g_signal_connect (G_OBJECT (check), "clicked",G_CALLBACK (toggle_show_text),pdata);
gtk_widget_show (check);
/* 添加一個復選按鈕,切換活動狀態 */
check =gtk_check_button_new_with_label ("Activity mode");
gtk_table_attach (GTK_TABLE (table), check, 0, 1, 1, 2,GTK_EXPAND |GTK_FILL, GTK_EXPAND |GTK_FILL,5, 5);
g_signal_connect (G_OBJECT (check), "clicked",G_CALLBACK (toggle_activity_mode),pdata);
gtk_widget_show (check);
/* 添加一個復選按鈕,切換移動方向 */
check =gtk_check_button_new_with_label ("Right to Left");
gtk_table_attach (GTK_TABLE (table), check, 0, 1, 2, 3,GTK_EXPAND |GTK_FILL, GTK_EXPAND |GTK_FILL,5, 5);
g_signal_connect (G_OBJECT (check), "clicked",G_CALLBACK (toggle_orientation),pdata);
gtk_widget_show (check);
/* 添加一個按鈕,用來退出應用程序 */
button =gtk_button_new_with_label ("close");
g_signal_connect_swapped (G_OBJECT (button), "clicked",G_CALLBACK (gtk_widget_destroy),pdata->window);
gtk_box_pack_start (GTK_BOX(vbox), button, FALSE, FALSE, 0);
/* 將按鈕設置為能缺省的構件 */
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
/* 將缺省焦點設置到這個按鈕上,使之成為缺省按鈕,只要按回車鍵
* 就相當于點擊了這個按鈕 */
//譯者注: 能缺省的構件在獲取焦點后成為缺省構件,用戶按方向鍵等可以切換焦點。
gtk_widget_grab_default (button);
gtk_widget_show (button);
gtk_widget_show (pdata->window);
gtk_main ();
return 0;
}
~~~
運行如下:

參考 資料:
??[http://guoyinghui2012.blog.163.com/blog/static/20871720020126294943228/](http://guoyinghui2012.blog.163.com/blog/static/20871720020126294943228/)