嵌入式成长轨迹23 【Linux应用编程强化】【Linux下的C编程 下】【Linux GUI编程】

 

 

一   GTK+/Gnome开发简介

GTK+是一个用于创建图形用户界面(GUI)的图形库,它在功能上类似微软的MFC,为应用程序提供了一套与平台无关的图形用户接口。GTK+最初用于开发GIMP(General Image Manipulation Program),因而称为GTK(GIMP Toolkit)。

 

1         第一个GTK+应用程序

GtkWidget *gtk_window_new(GtkWindowType windowtype);

GTK_WINDOW_TOPLEVEL

GTK_WINDOW_DIALOG

GTK_WINDOW_POPUP

void gtk_widget_show(GtkWidget *widget);

void gtk_main(void);

 

 1 /* hello.c */
 2 
 3 #include<gtk/gtk.h>                          
 4 
 5 int main(int argc, char **argv[])
 6 
 7 {
 8 
 9   GtkWidget *window;              
10 
11   gtk_init(&argc, &argv);                 
12 
13   window = gtk_window_new(GTK_WINDOW_TOPLEVEL);       
14 
15   gtk_widget_show(window);                  
16 
17   gtk_main();                            
18 
19   return 0;
20 
21 }

 

 

2         信号连接回调函数

#define gtk_signal_connect(object, name, func, func_data) \

   gtk_signal_connect_full((object), (name), (func), 0, (func_data), 0, 0, 0)

gulong gtk_signal_connect_full(GtkObject *object, const gchar *name, GtkSignalFunc func, \

   GtkCallbackMarshal unsupported, gpointer data, GtkDestroyNotify destroy_func, \

   gint object_signal, gint after);

 

void callback_func(GtkWidget *widget, gpointer callback_data );

 

#define gtk_signal_connect_object(object, name, func, slot_object) \

   gtk_signal_connect_full ((object), (name), (func), 0, (slot_object), 0, 1, 0)

gulong gtk_signal_connect_full(GtkObject *object, const gchar *name, GtkSignalFunc func, \

   GtkCallbackMarshal unsupported, gpointer data, GtkDestroyNotify destroy_func, \

   gint object_signal, gint after);

 

void callback_func( GtkObject *object );

 

 

 1 /* hello2.c */
 2 
 3 #include <gtk/gtk.h>
 4 
 5 void hello(GtkWidget *widget, gpointer data )          
 6 
 7 {
 8 
 9   g_print ("Hello World!\n");
10 
11 }
12 
13 gint delete_event(GtkWidget *widget, GdkEvent *event, gpointer data)
14 
15 {
16 
17   g_print ("delete event occurred\n");
18 
19   return TUNE;
20 
21 }
22 
23 void destroy(GtkWidget *widget, gpointer data )
24 
25 {
26 
27   gtk_main_quit();
28 
29 }
30 
31 int main(int argc, char **argv)                         
32 
33 {
34 
35   GtkWidget *window;
36 
37   GtkWidget *button;
38 
39   gtk_init(&argc, &argv);                                      
40 
41   window = gtk_window_new(GTK_WINDOW_TOPLEVEL);                    
42 
43   gtk_signal_connect(GTK_OBJECT(window), "delete_event",
44 
45       GTK_SIGNAL_FUNC(delete_event), NULL);
46 
47   gtk_signal_connect(GTK_OBJECT(window), "destroy",
48 
49       GTK_SIGNAL_FUNC(destroy), NULL);
50 
51   gtk_container_set_border_width(GTK_CONTAINER (window), 30);
52 
53   button = gtk_button_new_with_label("Hello World");
54 
55   gtk_signal_connect(GTK_OBJECT(button), "clicked", G_CALLBACK(hello), NULL);
56 
57   gtk_container_add(GTK_CONTAINER(window), button);
58 
59   gtk_widget_show(button);
60 
61   gtk_widget_show(window);
62 
63   gtk_main();
64 
65   return 0;
66 
67 }

 

 

 1 /* table.c */
 2 
 3 #include <gtk/gtk.h>
 4 
 5 void callback1(GtkWidget *widget, gpointer data )           
 6 
 7 {
 8 
 9   g_print ("Button 1 clicked\n");
10 
11 }
12 
13 void callback2(GtkWidget *widget, gpointer data )
14 
15 {
16 
17   g_print ("Button 2 clicked\n");
18 
19 }
20 
21 gint delete_event(GtkWidget *widget, GdkEvent *event, gpointer data)
22 
23 {
24 
25   g_print ("delete event occurred\n");
26 
27   gtk_main_quit();
28 
29   return FALSE;
30 
31 }
32 
33 int main(int argc, char **argv)                                       
34 
35 {
36 
37   GtkWidget *window;
38 
39   GtkWidget *table;
40 
41   GtkWidget *button;
42 
43   gtk_init(&argc, &argv);                                      
44 
45   window = gtk_window_new(GTK_WINDOW_TOPLEVEL);      
46 
47   gtk_signal_connect(GTK_OBJECT(window), "delete_event",
48 
49       GTK_SIGNAL_FUNC(delete_event), NULL);
50 
51   gtk_container_set_border_width(GTK_CONTAINER (window), 15);   
52 
53   table = gtk_table_new(2, 2, TRUE);
54 
55   gtk_container_add (GTK_CONTAINER (window), table);    
56 
57   button = gtk_button_new_with_label("Button 1");
58 
59   gtk_signal_connect(GTK_OBJECT(button), "clicked", G_CALLBACK(callback1), NULL);
60 
61   gtk_table_attach_defaults (GTK_TABLE (table), button, 0, 1, 0, 1);
62 
63   gtk_widget_show (button);                    
64 
65   button = gtk_button_new_with_label("Button 2");
66 
67   gtk_signal_connect(GTK_OBJECT(button), "clicked", G_CALLBACK(callback2), NULL);
68 
69   gtk_table_attach_defaults (GTK_TABLE (table), button, 1, 2, 0, 1);
70 
71   gtk_widget_show (button);
72 
73   button = gtk_button_new_with_label("Exit");
74 
75   gtk_signal_connect(GTK_OBJECT(button), "clicked", G_CALLBACK(delete_event), NULL);
76 
77   gtk_table_attach_defaults (GTK_TABLE (table), button, 0, 2, 1, 2);
78 
79   gtk_widget_show (button);
80 
81   gtk_widget_show (table);
82 
83   gtk_widget_show(window);
84 
85   gtk_main();
86 
87   return 0;
88 
89 }

 

 

二  常用GTK+构件

GTK+中的构件非常丰富,这一节主要介绍其中部分常用的构件,例如按钮、标签、对话框等。下面首先讨论构件的定位。

1         构件定位

在用GTK+构件创建程序界面时,使用容器来实现构件的定位。GTK+中有两种容器,其中一种只能容纳一个子构件,例如GtkWindow;而另外一种则可以容纳多个子构件,例如GtkHBox、GtkVBox以及GtkTable等。

1).GtkWindow构件

       GtkWidget* gtk_window_new(GtkWindowType type);

       void gtk_window_set_title(GtkWindow *window, const gchar *title);

       void gtk_window_set_default_size(GtkWindow *window, gint width, gint height);

 

 

 

2).GtkBox构件

       GtkWidget* gtk_hbox_new(gboolean homogeneous,                gint spacing);

       GtkWidget* gtk_vbox_new(gboolean homogeneous,                gint spacing);

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

       void gtk_box_pack_end(GtkBox *box, GtkWidget                      *child, gint expand, gint fill, gint padding);

 

 

3).GtkTable构件

       GtkWidget *gtk_table_new( guint rows, guint columns, gboolean homogeneous);

 

       void gtk_table_attach(GtkTable *table, GtkWidget   *child, guint left_attach, guint right_attach, guint top_attach, guint bottom_attach, GtkAttachOptions xoptions, GtkAttachOptions yoptions, guint xpadding, guint ypadding);

 

       void gtk_table_attach_defaults(GtkTable *table, GtkWidget *widget, guint left_attach, guint right_attach, guint top_attach, guint bottom_attach);

 

2  按钮构件

1).普通按钮(GtkButton)

GtkWidget* gtk_button_new(void);

GtkWidget* gtk_button_new_with_label(const gchar *label);

2).开关按钮(GtkToggleButton)

GtkWidget *gtk_toggle_button_new(void);

GtkWidget *gtk_toggle_button_new_with_label(const gchar *label);

gboolean gtk_toggle_button_get_active (GtkToggleButton *toggle_button);

3).复选按钮(GtkCheckButton)

GtkWidget *gtk_check_button_new(void);

GtkWidget *gtk_check_button_new_with_label(const gchar *label);

4).单选按钮(GtkRadioButton)

GtkWidget *gtk_radio_button_new(CSList *group);

GtkWidget *gtk_radio_button_new_with_label(CSList *group, gchar *label);

GSList* gtk_radio_button_group(GtkRadioButton *radio_button);

 

 1 /* radio.c */
 2 
 3 #include <gtk/gtk.h>
 4 
 5 gint delete_event(GtkWidget *widget, GdkEvent *event, gpointer data)
 6 
 7 {
 8 
 9   g_print ("delete event occurred\n");
10 
11   gtk_main_quit();
12 
13   return FALSE;
14 
15 }
16 
17 int main(int argc, char **argv)                                        /* 主函数 */
18 
19 {
20 
21   GtkWidget *window;
22 
23   GtkWidget *vbox;
24 
25   GtkWidget *button;
26 
27   GSList *group;
28 
29   gtk_init(&argc, &argv);                                              /* 初始化 */
30 
31   window = gtk_window_new(GTK_WINDOW_TOPLEVEL);                     /* 创建主窗口 */
32 
33   /* 为delete_event事件连接一个回调函数 */
34 
35   gtk_signal_connect(GTK_OBJECT(window), "delete_event",
36 
37       GTK_SIGNAL_FUNC(delete_event), NULL);
38 
39   gtk_window_set_title(GTK_WINDOW (window), "radio");                 /* 设置窗口的标题 */
40 
41   gtk_container_set_border_width(GTK_CONTAINER (window), 15);    /* 设置窗口的边框宽度 */
42 
43   /* 创建一个垂直组装盒 */
44 
45   vbox = gtk_vbox_new(FALSE, 0);
46 
47   gtk_container_add(GTK_CONTAINER(window), vbox);                    /* 添加到主窗口之中 */
48 
49   gtk_widget_show(vbox);
50 
51   /* 创建第一个单选按钮 */
52 
53   button = gtk_radio_button_new_with_label(NULL, "radio button 1");
54 
55   gtk_box_pack_start(GTK_BOX(vbox), button, TRUE, TRUE, 0);        /* 将按钮添加到组装盒之中 */
56 
57   gtk_widget_show(button);
58 
59   group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button));                    /* 创建按钮组 */
60 
61   /* 创建第二个单选按钮 */
62 
63   button = gtk_radio_button_new_with_label(group, "radio button 2");
64 
65   gtk_box_pack_start(GTK_BOX(vbox), button, TRUE, TRUE, 0);
66 
67   gtk_widget_show(button);
68 
69   /* 创建第三个单选按钮 */
70 
71   button = gtk_radio_button_new_with_label(group, "radio button 3");
72 
73   gtk_box_pack_start(GTK_BOX(vbox), button, TRUE, TRUE, 0);
74 
75   gtk_widget_show(button);
76 
77   /* 显示主窗口 */
78 
79   gtk_widget_show(window);
80 
81   /* 事件循环 */
82 
83   gtk_main();
84 
85   return 0;
86 
87 }

 

 

 

3         标签构件

标签(GtkLabel)也是应用程序中经常使用的一种构件。

GtkWidget *gtk_label_new(const char *str );

gchar *gtk_label_get_text(GtkLabel *label);

void gtk_label_set_text(GtkLabel *label, const char *str);

void gtk_label_set_justify(GtkLabel *label, GtkJustification jtype);

GTK_JUSTIFY_LEFT:左对齐

GTK_JUSTIFY_RIGHT:右对齐

GTK_JUSTIFY_CENTER:居中对齐(默认)

GTK_JUSTIFY_FILL:填满

 

 1 /* labels.c */
 2 
 3 #include <gtk/gtk.h>
 4 
 5 int main(int argc, char **argv)
 6 
 7 {
 8 
 9   GtkWidget *window;
10 
11   GtkWidget *vbox;
12 
13   GtkWidget *label;
14 
15   gtk_init(&argc, &argv);                                              /* 初始化 */
16 
17   window = gtk_window_new(GTK_WINDOW_TOPLEVEL);                     /* 创建主窗口 */
18 
19   gtk_signal_connect(GTK_OBJECT(window), "destroy",
20 
21       GTK_SIGNAL_FUNC(gtk_main_quit), NULL);
22 
23   gtk_window_set_title(GTK_WINDOW (window), "label");                 /* 设置窗口的标题 */
24 
25   gtk_container_set_border_width(GTK_CONTAINER (window), 15);    /* 设置窗口的边框宽度 */
26 
27   /* 创建一个垂直组装盒 */
28 
29   vbox = gtk_vbox_new(FALSE, 0);
30 
31   gtk_container_add(GTK_CONTAINER(window), vbox);                    /* 添加到主窗口之中 */
32 
33   /* 创建第一个标签 */
34 
35   label = gtk_label_new("Line 1: Hello\nLine 2 : World");
36 
37   gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_RIGHT);
38 
39   gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 0);
40 
41   /* 创建第二个标签 */
42 
43   label = gtk_label_new("Line 3 : Linux\nLine 4 : Programming ");
44 
45   gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
46 
47   gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 0);
48 
49   /* 显示所有构件 */
50 
51   gtk_widget_show_all(window);
52 
53   /* 事件循环 */
54 
55   gtk_main();
56 
57   return 0;
58 
59 }

 

 

 

4         文本及文本输入构件

文本构件和文本输入构件是两个比较常用的构件,用于显示和编辑文本。

1).文本构件

2).文本输入构件

 

  1 /* text.c */
  2 
  3 #include <gtk/gtk.h>
  4 
  5 void editable_toggle(GtkWidget *widget, GtkWidget *text)      /* 复选框回调函数 */
  6 
  7 {
  8 
  9   gtk_editable_set_editable(GTK_EDITABLE(text),
 10 
 11       GTK_TOGGLE_BUTTON(widget)->active);
 12 
 13 }
 14 
 15  
 16 
 17 gint delete_event(GtkWidget *widget,                              /* 退出按钮回调函数 */
 18 
 19       GdkEvent *event, gpointer data)
 20 
 21 {
 22 
 23   gtk_main_quit();
 24 
 25   return FALSE;
 26 
 27 }
 28 
 29  
 30 
 31 int main(int argc, char **argv)                                               /* 主函数 */
 32 
 33 {
 34 
 35   GtkWidget *window;
 36 
 37   GtkWidget *vbox, *hbox;
 38 
 39   GtkWidget *text;
 40 
 41   GtkWidget *check;
 42 
 43   GtkWidget *button;
 44 
 45   gtk_init(&argc, &argv);                                                     /* 初始化 */
 46 
 47   /* 创建主窗口 */
 48 
 49   window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
 50 
 51   gtk_signal_connect(GTK_OBJECT(window), "destroy",
 52 
 53       GTK_SIGNAL_FUNC(gtk_main_quit), NULL);
 54 
 55   gtk_window_set_title(GTK_WINDOW (window), "text");
 56 
 57   gtk_container_set_border_width(GTK_CONTAINER (window), 15);
 58 
 59   /* 创建一个垂直组装盒 */
 60 
 61   vbox = gtk_vbox_new(FALSE, 0);
 62 
 63   gtk_container_add(GTK_CONTAINER(window), vbox);
 64 
 65   /* 创建一个文本构件 */
 66 
 67   text = gtk_text_new(NULL, NULL);
 68 
 69   gtk_text_insert(text, NULL, NULL,                /* 插入文本使用系统默认字体和颜色*/
 70 
 71       NULL, "Source Code :", -1);
 72 
 73   gtk_box_pack_start(GTK_BOX(vbox), text, TRUE, TRUE, 0);
 74 
 75   /* 创建一个水平组装盒 */
 76 
 77   hbox = gtk_hbox_new(FALSE, 0);
 78 
 79   gtk_container_add(GTK_CONTAINER(vbox), hbox);
 80 
 81   /* 创建一个复选按钮 */
 82 
 83   check = gtk_check_button_new_with_label("Editable");
 84 
 85   gtk_signal_connect(GTK_OBJECT(check), "toggled",
 86 
 87       GTK_SIGNAL_FUNC(editable_toggle), text);
 88 
 89   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), TRUE);
 90 
 91   gtk_box_pack_start(GTK_BOX(hbox), check, TRUE, TRUE, 0);
 92 
 93   /* 创建退出按钮 */
 94 
 95   button = gtk_button_new_with_label("Exit");
 96 
 97   gtk_signal_connect(GTK_OBJECT(button), "clicked",
 98 
 99       G_CALLBACK(delete_event), NULL);
100 
101   gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
102 
103   /* 显示所有构件 */
104 
105   gtk_widget_show_all(window);
106 
107   /* 事件循环 */
108 
109   gtk_main();
110 
111   return 0;
112 
113 }

 

 

  1 /* entry.c */
  2 
  3 #include <gtk/gtk.h>
  4 
  5 void enter_callback(GtkWidget *widget, gpointer data)             /* 回调函数 */
  6 
  7 {
  8 
  9   const gchar *entry_text;
 10 
 11   entry_text = gtk_entry_get_text(GTK_ENTRY(widget));
 12 
 13   printf("Entry contents : %s\n", entry_text);
 14 
 15 }
 16 
 17 void editable_toggle(GtkWidget *widget, GtkWidget *entry)
 18 
 19 {
 20 
 21   gtk_editable_set_editable(GTK_EDITABLE(entry), GTK_TOGGLE_BUTTON(widget)->active);
 22 
 23 }
 24 
 25 gint delete_event(GtkWidget *widget, GdkEvent *event, gpointer data)
 26 
 27 {
 28 
 29   gtk_main_quit();
 30 
 31   return FALSE;
 32 
 33 }
 34 
 35 int main(int argc, char **argv)                                               /* 主函数 */
 36 
 37 {
 38 
 39   GtkWidget *window;
 40 
 41   GtkWidget *vbox, *hbox;
 42 
 43   GtkWidget *entry;
 44 
 45   GtkWidget *check;
 46 
 47   GtkWidget *button;
 48 
 49   gtk_init(&argc, &argv);                                                     /* 初始化 */
 50 
 51   /* 创建主窗口 */
 52 
 53   window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
 54 
 55   gtk_signal_connect(GTK_OBJECT(window), "destroy",
 56 
 57       GTK_SIGNAL_FUNC(gtk_main_quit), NULL);
 58 
 59   gtk_window_set_title(GTK_WINDOW (window), "label");
 60 
 61   gtk_container_set_border_width(GTK_CONTAINER (window), 15);
 62 
 63   /* 创建一个垂直组装盒 */
 64 
 65   vbox = gtk_vbox_new(FALSE, 0);
 66 
 67   gtk_container_add(GTK_CONTAINER(window), vbox);
 68 
 69   /* 创建一个文本输入构件 */
 70 
 71   entry = gtk_entry_new();
 72 
 73   gtk_signal_connect(GTK_OBJECT(entry), "activate", GTK_SIGNAL_FUNC(enter_callback), NULL);
 74 
 75   gtk_box_pack_start(GTK_BOX(vbox), entry, TRUE, TRUE, 0);
 76 
 77   /* 创建一个水平组装盒 */
 78 
 79   hbox = gtk_hbox_new(FALSE, 0);
 80 
 81   gtk_container_add(GTK_CONTAINER(vbox), hbox);
 82 
 83   /* 创建一个复选按钮 */
 84 
 85   check = gtk_check_button_new_with_label("Editable");
 86 
 87   gtk_signal_connect(GTK_OBJECT(check), "toggled", GTK_SIGNAL_FUNC(editable_toggle), entry);
 88 
 89   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), TRUE);
 90 
 91   gtk_box_pack_start(GTK_BOX(hbox), check, TRUE, TRUE, 0);
 92 
 93   /* 创建Exit按钮 */
 94 
 95   button = gtk_button_new_with_label("Exit");
 96 
 97   gtk_signal_connect(GTK_OBJECT(button), "clicked", G_CALLBACK(delete_event), NULL);
 98 
 99   gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
100 
101   /* 显示所有构件 */
102 
103   gtk_widget_show_all(window);
104 
105   /* 事件循环 */
106 
107   gtk_main();
108 
109   return 0;
110 
111 }

 

 

5         进度条构件

进度条构件(GtkProgressBar)一般用来显示应用程序中某个操作的状态。

 

  1 /* progressbar.c */
  2 
  3 #include <gtk/gtk.h>
  4 
  5 gint started;                                              /* 状态标志 */
  6 
  7 gint paused;
  8 
  9 gint progress(gpointer data )                       /* 更新进度条 */
 10 
 11 {
 12 
 13   gfloat i;
 14 
 15   GtkAdjustment *adj;                              /* 调整对象 */
 16 
 17   i = gtk_progress_get_value(GTK_PROGRESS(data));           /* 获取进度条的当前值 */
 18 
 19   if(0 == started)                                                         /* 判断进度更新是否被停止 */
 20 
 21   {
 22 
 23     if(0 == paused)                                                            /* 判断进度更新是否被暂停 */
 24 
 25     {
 26 
 27       i = i + 1;
 28 
 29       paused = 0;
 30 
 31     }
 32 
 33   }
 34 
 35   else
 36 
 37   {
 38 
 39     i = 100;
 40 
 41   }
 42 
 43   adj = GTK_PROGRESS (data)->adjustment;
 44 
 45   if (i > adj->upper)                                                             /* 判断是否超出取值范围 */
 46 
 47   {
 48 
 49     i = adj->lower;
 50 
 51   }
 52 
 53   gtk_progress_set_value(GTK_PROGRESS (data), i);             /* 更新进度条 */
 54 
 55   return (TRUE ) ;
 56 
 57 }
 58 
 59  
 60 
 61 void show_toggle(GtkWidget *widget, GtkWidget *pbar)         /* 显示文本复选框回调函数 */
 62 
 63 {
 64 
 65   gtk_progress_set_show_text(GTK_PROGRESS(pbar),
 66 
 67       GTK_TOGGLE_BUTTON(widget)->active);
 68 
 69 }
 70 
 71  
 72 
 73 gint start_event(GtkWidget *widget, gpointer data)                   /* 开始按钮回调函数 */
 74 
 75 {
 76 
 77   gfloat i;
 78 
 79   i = gtk_progress_get_value(GTK_PROGRESS(pbar));          /* 获取进度条的当前值 */
 80 
 81   if(100 == i)
 82 
 83   {
 84 
 85     started = 0;                                                             /* 设置状态标志*/
 86 
 87     paused = 0;
 88 
 89   }
 90 
 91   return TRUE;
 92 
 93 }
 94 
 95  
 96 
 97 gint pause_event(GtkWidget *widget, gpointer data)                 /* 暂停按钮回调函数 */
 98 
 99 {
100 
101   if(0 == paused)                                                           /* 判断是否已经暂停 */
102 
103   {
104 
105     paused = 1;
106 
107   }
108 
109   else                                                                           /* 如果已经暂停,则取消暂停 */
110 
111   {
112 
113     paused = 0;
114 
115   }
116 
117   return TRUE;
118 
119 }
120 
121  
122 
123 gint stop_event(GtkWidget *widget, gpointer data)                   /* 停止按钮回调函数 */
124 
125 {
126 
127   started = 1;                                                                       /* 设置状态标志*/
128 
129   paused = 1;
130 
131   return TRUE;
132 
133 }
134 
135  
136 
137 gint delete_event(GtkWidget *widget,                              /* 关闭按钮回调函数 */
138 
139     GdkEvent *event, gpointer data)
140 
141 {
142 
143   gtk_main_quit();
144 
145   return FALSE;
146 
147 }
148 
149  
150 
151 int main(int argc, char **argv)                                               /* 主函数 */
152 
153 {
154 
155   GtkWidget *window;
156 
157   GtkWidget *vbox, *hbox;
158 
159   GtkWidget *pbar;
160 
161   GtkWidget *check;
162 
163   GtkWidget *button;
164 
165  
166 
167   gtk_init(&argc, &argv);                                                     /* 初始化 */
168 
169   /* 创建主窗口 */
170 
171   window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
172 
173   gtk_signal_connect(GTK_OBJECT(window), "destroy",
174 
175       GTK_SIGNAL_FUNC(gtk_main_quit), NULL);
176 
177   gtk_window_set_title(GTK_WINDOW (window), "progressbar");
178 
179   gtk_container_set_border_width(GTK_CONTAINER (window), 15);
180 
181   /* 创建一个垂直组装盒 */
182 
183   vbox = gtk_vbox_new(FALSE, 0);
184 
185   gtk_container_add(GTK_CONTAINER(window), vbox);
186 
187   /* 创建进度条构件 */
188 
189   pbar = gtk_progress_bar_new();
190 
191   gtk_progress_bar_set_bar_style(                     /* 设置进度条构件更新方式 */
192 
193       GTK_PROGRESS_BAR(pbar), GTK_PROGRESS_CONTINUOUS);
194 
195   gtk_progress_set_format_string(                     /* 如果显示文本,指定其格式 */
196 
197       GTK_PROGRESS(pbar), "%p");
198 
199   gtk_timeout_add (100, progress, pbar);           /* 对进度条进行连续更新,间隔时间为0.1s */
200 
201   gtk_box_pack_start(GTK_BOX(vbox), pbar, TRUE, TRUE, 0);
202 
203   /* 创建一个水平组装盒 */
204 
205   hbox = gtk_hbox_new(FALSE, 0);
206 
207   gtk_container_add(GTK_CONTAINER(vbox), hbox);
208 
209   /* 创建显示文本复选按钮 */
210 
211   check = gtk_check_button_new_with_label("Show Text");
212 
213   gtk_signal_connect(GTK_OBJECT(check), "toggled",
214 
215       GTK_SIGNAL_FUNC(show_toggle), pbar);
216 
217   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), TRUE);
218 
219   gtk_box_pack_start(GTK_BOX(hbox), check, TRUE, TRUE, 0);
220 
221   /* 创建一个水平组装盒 */
222 
223   hbox = gtk_hbox_new(FALSE, 0);
224 
225     gtk_container_add(GTK_CONTAINER(vbox), hbox);
226 
227   /* 创建开始按钮 */
228 
229   button = gtk_button_new_with_label("start");
230 
231   gtk_signal_connect(GTK_OBJECT(button), "clicked",
232 
233       G_CALLBACK(start_event), pbar);
234 
235   gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
236 
237   /* 创建暂停按钮 */
238 
239   button = gtk_button_new_with_label("Pause");
240 
241   gtk_signal_connect(GTK_OBJECT(button), "clicked",
242 
243       G_CALLBACK(pause_event), NULL);
244 
245   gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
246 
247   /* 创建停止按钮 */
248 
249   button = gtk_button_new_with_label("Stop");
250 
251   gtk_signal_connect(GTK_OBJECT(button), "clicked",
252 
253       G_CALLBACK(stop_event), NULL);
254 
255   gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
256 
257   /* 创建关闭按钮 */
258 
259   button = gtk_button_new_with_label("Close");
260 
261   gtk_signal_connect(GTK_OBJECT(button), "clicked",
262 
263       G_CALLBACK(delete_event), NULL);
264 
265   gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
266 
267   /* 显示所有构件 */
268 
269   gtk_widget_show_all(window);
270 
271   /* 事件循环 */
272 
273   gtk_main();
274 
275   return 0;
276 
277 }

 

 

6         组合框

组合框构件(GtkCombo)在应用程序中经常用到,它包含一个文本输入框和一个下拉列表,用户可以在下拉列表中进行选择,也可以在文本框中直接输入文本。

 

  1 /* combo.c */
  2 
  3 #include <gtk/gtk.h>
  4 
  5 #define N 16
  6 
  7 typedef struct _Calculate                                   /* 定义结构体,用来向回调函数传递参数 */
  8 
  9 {
 10 
 11   GtkWidget *entry1;
 12 
 13   GtkWidget *entry2;
 14 
 15   GtkWidget *combo;
 16 
 17   GtkWidget *label;
 18 
 19 } Calculate;
 20 
 21  
 22 
 23 gint cal_event(GtkWidget *widget, Calculate *cal)             /* 计算按钮回调函数 */
 24 
 25 {
 26 
 27   const gchar *text1, *text2;
 28 
 29   const char *options;
 30 
 31   gchar result[N];
 32 
 33   char operator;
 34 
 35   gint x, y, z;
 36 
 37   gint flag;
 38 
 39   text1 = gtk_entry_get_text(                            /* 获取文本输入构件中的字符串 */
 40 
 41       GTK_ENTRY(cal->entry1));
 42 
 43   x = atoi(text1);                                     /* 将得到的字符串转换为整数 */
 44 
 45   text2 = gtk_entry_get_text(                            /* 获取文本输入构件中的字符串 */
 46 
 47       GTK_ENTRY(cal->entry2));
 48 
 49   y = atoi(text2);                                     /* 将得到的字符串转换为整数 */
 50 
 51   options = gtk_entry_get_text(                         /* 获取组合框构件中用户选择的字符串 */
 52 
 53       GTK_ENTRY(GTK_COMBO(cal->combo)->entry));
 54 
 55   operator = *options;                              /* 提取运算符 */
 56 
 57   flag = 0;                                                      /* 出错标志,用于后面的错误检测 */
 58 
 59   switch (operator)                                          /* 对两个操作数进行运算 */
 60 
 61   {
 62 
 63     case '+':                                             /* 加法运算 */
 64 
 65       z = x + y;
 66 
 67       break;
 68 
 69     case '-':                                             /* 减法运算 */
 70 
 71       z = x - y;
 72 
 73       break;
 74 
 75     case 'x':                                             /* 乘法运算 */
 76 
 77       z = x * y;
 78 
 79       break;
 80 
 81     case '/':                                              /* 除法运算 */
 82 
 83       if(0 == y)                                             /* 除数为0时,设置出错标志 */
 84 
 85         flag = 1;
 86 
 87       else
 88 
 89         z = x / y;
 90 
 91       break;
 92 
 93     case '%':                                            /* 取余运算 */
 94 
 95       if(0 == y)                                      /* 除数为0时,设置出错标志 */
 96 
 97         flag = 1;
 98 
 99       else
100 
101         z = x % y;
102 
103       break;
104 
105     default:                                             /* 其余情况,设置出错标志 */
106 
107       flag = 1;
108 
109   }
110 
111   if(1 == flag)                                                /* 检测出错标志 */
112 
113     g_sprintf(result, "error");
114 
115   else
116 
117 g_sprintf(result, "%d", z);                         /* 将运算结果转换为字符串 */
118 
119   gtk_label_set_text(GTK_LABEL(cal->label), result);      /* 输出运算结果或出错提示 */
120 
121   return TRUE;
122 
123 }
124 
125  
126 
127 gint close_event(GtkWidget *widget,          /* 关闭按钮回调函数 */
128 
129     GdkEvent *event, gpointer data)
130 
131 {
132 
133   gtk_main_quit();
134 
135   return TRUE;
136 
137 }
138 
139  
140 
141 int main(int argc, char **argv)                          /* 主函数 */
142 
143 {
144 
145   Calculate *cal;
146 
147   GtkWidget *window;
148 
149   GtkWidget *table;
150 
151   GtkWidget *label;
152 
153   GtkWidget *button;
154 
155  
156 
157   gtk_init(&argc, &argv);                                /* 初始化 */
158 
159   /* 创建主窗口 */
160 
161   window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
162 
163   gtk_signal_connect(GTK_OBJECT(window), "destroy",
164 
165       GTK_SIGNAL_FUNC(gtk_main_quit), NULL);
166 
167   gtk_window_set_title(GTK_WINDOW (window), "combo");
168 
169   gtk_container_set_border_width(GTK_CONTAINER (window), 15);
170 
171   /* 创建一个6x2的网格 */
172 
173   table = gtk_table_new(6, 2, TRUE);
174 
175   gtk_container_add(                                /* 将网格添加到主窗口之中 */
176 
177       GTK_CONTAINER (window), table);
178 
179   /* 创建一个文本输入构件,用于操作数输入 */
180 
181   cal->entry1 = gtk_entry_new();
182 
183   gtk_table_attach_defaults(                       /* 将文本输入构件放到网格之中 */
184 
185       GTK_TABLE (table), cal->entry1, 0, 2, 0, 1);
186 
187   /* 创建一个组合框构件,用于操作符选择 */
188 
189   cal->combo = gtk_combo_new();
190 
191   GList *glist=NULL;                                      /* 定义Glist链表 */
192 
193   glist = g_list_append(glist, "+");                     /* 向Glist链表中追加字符串 */
194 
195   glist = g_list_append(glist, "-");
196 
197   glist = g_list_append(glist, "x");
198 
199   glist = g_list_append(glist, "/");
200 
201   glist = g_list_append(glist, "%");
202 
203   gtk_combo_set_popdown_strings(                  /* 设置下拉列表中选项 */
204 
205       GTK_COMBO(cal->combo), glist);
206 
207   gtk_entry_set_text(GTK_ENTRY(                  /* 文本输入框中显示文本 */
208 
209       GTK_COMBO(cal->combo)->entry), "operator");
210 
211   gtk_table_attach_defaults (                      /* 将组合框构件放到网格之中 */
212 
213       GTK_TABLE (table), cal->combo, 0, 2, 1, 2);
214 
215   /* 创建一个文本输入构件,用于操作数输入 */
216 
217   cal->entry2 = gtk_entry_new();
218 
219   gtk_table_attach_defaults (                      /* 将文本输入构件放到网格之中 */
220 
221       GTK_TABLE (table),cal->entry2, 0, 2, 2, 3);
222 
223   /* 创建计算按钮 */
224 
225   button = gtk_button_new_with_label("Calulate");
226 
227   gtk_signal_connect(GTK_OBJECT(button), "clicked",
228 
229       G_CALLBACK(cal_event), cal);
230 
231   gtk_table_attach_defaults (                      /* 将按钮构件放到网格之中 */
232 
233       GTK_TABLE (table), button, 0, 2, 3, 4);
234 
235   /* 创建一个标签构件 */
236 
237   label = gtk_label_new("Result : ");
238 
239   gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
240 
241   gtk_table_attach_defaults (                      /* 将标签构件放到网格之中 */
242 
243       GTK_TABLE (table), label, 0, 1, 4, 5);
244 
245   /* 创建一个标签构件,用于计算结果显示 */
246 
247   cal->label = gtk_label_new(" ");
248 
249   gtk_label_set_justify(GTK_LABEL(cal->label), GTK_JUSTIFY_CENTER);
250 
251   gtk_table_attach_defaults (                      /* 将标签构件放到网格之中 */
252 
253       GTK_TABLE (table), cal->label, 1, 2, 4, 5);
254 
255   /* 创建关闭按钮 */
256 
257   button = gtk_button_new_with_label("Close");
258 
259   gtk_signal_connect(GTK_OBJECT(button), "clicked",
260 
261       G_CALLBACK(close_event), NULL);
262 
263   gtk_table_attach_defaults (                      /* 将按钮构件放到网格之中 */
264 
265       GTK_TABLE (table), button, 1, 2, 5, 6);
266 
267   /* 显示所有构件 */
268 
269   gtk_widget_show_all(window);
270 
271   /* 事件循环 */
272 
273   gtk_main();
274 
275   return 0;
276 
277 }

 

 

7         对话框

对话框(GtkDialog)主要用来弹出消息,或完成一些类似任务

 

  1 /* dialog.c */
  2 
  3 #include <gtk/gtk.h>
  4 
  5 #define N 64
  6 
  7 gint yes_callback(GtkWidget *widget, gpointer data)         /* yes按钮回调函数 */
  8 
  9 {
 10 
 11   gtk_main_quit();
 12 
 13   return TRUE;
 14 
 15 }
 16 
 17  
 18 
 19 gint no_callback(GtkWidget *widget, gpointer data)          /* no按钮回调函数 */
 20 
 21 {
 22 
 23   gchar text[N];
 24 
 25   static gint i;                                                         /* 纪录按钮按下的次数 */
 26 
 27   i++;
 28 
 29   g_sprintf(text, "\"No\" button clicked %d times.", i);
 30 
 31   gtk_label_set_text(GTK_LABEL(data), text);                /* 设置标签构件显示的文本 */
 32 
 33   return TRUE;
 34 
 35 }
 36 
 37  
 38 
 39 int main(int argc, char **argv)                                        /* 主函数 */
 40 
 41 {
 42 
 43   GtkWidget *window;
 44 
 45   GtkWidget *label;
 46 
 47   GtkWidget *button;
 48 
 49   gtk_init(&argc, &argv);                                              /* 初始化 */
 50 
 51   /* 创建对话框 */
 52 
 53   window = gtk_dialog_new(); 
 54 
 55   /* 创建并添加标签构件 */
 56 
 57   label = gtk_label_new("\nDo you want to exit?\n");
 58 
 59   gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
 60 
 61   gtk_box_pack_start(                                             /* 添加到对话框上方的垂直组装盒中 */
 62 
 63       GTK_BOX (GTK_DIALOG (window)->vbox), label, TRUE, TRUE, 0);
 64 
 65   /* 创建并添加标签构件 */
 66 
 67   label = gtk_label_new(" ");
 68 
 69   gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_CENTER);
 70 
 71   gtk_box_pack_start(                                             /* 添加到对话框上方的垂直组装盒中 */
 72 
 73       GTK_BOX (GTK_DIALOG (window)->vbox), label, TRUE, TRUE, 0);
 74 
 75   /* 创建并添加按钮构件 */
 76 
 77   button = gtk_button_new_with_label("Yes");
 78 
 79   gtk_signal_connect(                                             /* 设置回调函数 */
 80 
 81       GTK_OBJECT(button), "clicked", G_CALLBACK(yes_callback), NULL);
 82 
 83   gtk_box_pack_start(                                             /* 添加到对话框下方的活动区域中 */
 84 
 85       GTK_BOX(GTK_DIALOG (window)->action_area), button, TRUE, TRUE, 0);
 86 
 87   /* 创建并添加按钮构件 */
 88 
 89   button = gtk_button_new_with_label("No");
 90 
 91   gtk_signal_connect(                                             /* 设置回调函数 */
 92 
 93       GTK_OBJECT(button), "clicked", G_CALLBACK(no_callback), label);
 94 
 95   gtk_box_pack_start(                                             /* 添加到对话框下方的活动区域中 */
 96 
 97       GTK_BOX(GTK_DIALOG (window)->action_area), button, TRUE, TRUE, 0);
 98 
 99   /* 显示所有构件 */
100 
101   gtk_widget_show_all(window);
102 
103   /* 事件循环 */
104 
105   gtk_main();
106 
107   return 0;
108 
109 }

 

 

  1 /* aboutdialog.c */
  2 
  3 #include <gtk/gtk.h>
  4 
  5 #include <libgnomeui/gnome-about.h>                      /* 注意包含该头文件 */
  6 
  7 #define N 64
  8 
  9  
 10 
 11 gint about_callback(GtkWidget *widget, gpointer data)     /* 关于按钮回调函数 */
 12 
 13 {
 14 
 15   GtkWidget *about;
 16 
 17   const gchar *authors[] = {                                    /* 软件作者信息 */
 18 
 19     "Xxxxxx Xxx <xxxxxx@kernel.org>",
 20 
 21     "Xxxxxx Xxx <xxxxxx@gnome.org>",
 22 
 23     "Xxxxxx Xxx <xxxxxx@gnome.org>",
 24 
 25     NULL
 26 
 27   };
 28 
 29   const gchar *documenters[] = {                             /* 文档作者信息 */
 30 
 31     "Xxxxxx Xxx <xxxxxx@gnome.org>",
 32 
 33     NULL
 34 
 35   };
 36 
 37   about = gnome_about_new ("XXXX", "1.00",               /* 创建Gnome关于对话框 */
 38 
 39       "(C) 2009 the Free Software Foundation",
 40 
 41       "comments ... ",
 42 
 43       authors,
 44 
 45       documenters,
 46 
 47       NULL,
 48 
 49       NULL) ;
 50 
 51   gtk_widget_show(about);                                     /* 显示Gnome关于对话框 */
 52 
 53   return TRUE;
 54 
 55 }
 56 
 57  
 58 
 59 gint close_callback(GtkWidget *widget, gpointer data)       /* 关闭按钮回调函数 */
 60 
 61 {
 62 
 63   gtk_main_quit();
 64 
 65   return TRUE;
 66 
 67 }
 68 
 69  
 70 
 71 int main(int argc, char **argv)                                        /* 主函数 */
 72 
 73 {
 74 
 75   GtkWidget *window;
 76 
 77   GtkWidget *vbox;
 78 
 79   GtkWidget *button;
 80 
 81  
 82 
 83   gtk_init(&argc, &argv);                                              /* 初始化 */
 84 
 85   /* 创建主窗口 */
 86 
 87   window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
 88 
 89   gtk_signal_connect(GTK_OBJECT(window), "destroy",
 90 
 91       GTK_SIGNAL_FUNC(gtk_main_quit), NULL);
 92 
 93   gtk_window_set_title(GTK_WINDOW (window), "combo");
 94 
 95   gtk_container_set_border_width(GTK_CONTAINER (window), 15);
 96 
 97   /* 创建一个垂直组装盒 */
 98 
 99   vbox = gtk_vbox_new(FALSE, 0);
100 
101   gtk_container_add(GTK_CONTAINER(window), vbox);
102 
103   /* 创建关于按钮 */
104 
105   button = gtk_button_new_with_label("About");
106 
107   gtk_signal_connect(GTK_OBJECT(button), "clicked",
108 
109       G_CALLBACK(about_callback), NULL);
110 
111   gtk_box_pack_start(GTK_BOX(vbox), button, TRUE, TRUE, 0);
112 
113   /* 创建关闭按钮 */
114 
115   button = gtk_button_new_with_label("Close");
116 
117   gtk_signal_connect(GTK_OBJECT(button), "clicked",
118 
119       G_CALLBACK(close_callback), NULL);
120 
121   gtk_box_pack_start(GTK_BOX(vbox), button, TRUE, TRUE, 0);
122 
123   /* 显示所有构件 */
124 
125   gtk_widget_show_all(window);
126 
127   /* 事件循环 */
128 
129   gtk_main();
130 
131   return 0;
132 
133 }

 

 

三  GUI生成器Glade

Glade是针对GTK+/Gnome快速图形界面开发的应用软件,它类似于Microsoft Windows环境下的VB、VC++以及Delphi等。Glade的可视化编程可以使程序员的主要精力集中于应用程序核心功能的开发上,而不需为界面的修改重复编写大量烦琐的Gtk+函数。

1         打开Glade

Linux系统启动图形界面之后,在终端上输入glade或在桌面上单击【Application】|【Programming】|【Glade Interface Designer】命令,即可启动Glade。一般能看到3个窗口:工程管理窗口、常用构件窗口和属性管理窗口。

 

2         创建应用程序界面

在创建应用程序界面之前,首先新建一个工程项目。单击工程管理窗口上方的【New】按钮,会弹出新建Project对话框。

1).创建一个新的窗口

2).在窗口中添加各种构件

3).为构件的信号连接回调函数

4).生成创建应用程序界面的源代码

 

3         编译连接程序

Glade中使用Automake工具,可以根据编译选项自动生成Makefile文件。

 

四  常见面试题

常见面试题1:简述编写GTK+应用程序的一般步骤。

 

常见面试题2:Glade的可视化编程与Microsoft Windows环境下的VB、VC++以及Delphi等工具有何差异?

 

五 小结

在Linux系统中,基于GTK+构件的应用程序图形界面,执行效率高,占用资源少,有着很好的发展前景。这一章主要介绍了GTK+编程的基本知识,通过本章的学习,读者应该能够编写基本的图形界面应用程序。由于篇幅有限,这里只介绍了很少一部分GTK+构件。

posted @ 2012-04-09 17:58  MooreZHENG  阅读(357)  评论(0编辑  收藏  举报