Linux下图形界面编程——GTK+元件、信号与回调函数

GTK界面基本元件

需要包含#include<gtk/gtk.h>


窗口

1.         新建窗口

gtk_window_new()可以建立一个GTK+窗口,函数原型如下:

GtkWidget * gtk_window_new (GtkWindowType type);

返回:若成功则返回GtkWidget类型的指针,失败则返回NULL。

参数type是一个表示窗口状态的常量,可能取值有以下两种:

  •   GTK_WINDOW_TOPLEVEL:表示该窗口是一个正常的窗口,可以最小化。
  •   GTK_WINDOW_POPUP:表示该窗口是一个弹出式的窗口,不可以最小化。

2.         设置窗口标题

gtk_window_set_title()函数用于设置窗口标题,使用方法如下:

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

参数window指定将要添加标题的窗口,title表示需要设置的标题。需要注意title指向的字符串必须是英文字符,若需要显示中文字符,则需要使用g_locale_to_utf8()函数进行批注。

3.         设置窗口大小与位置

窗口大小指的是窗口的宽度和高度,用gtk_widget_set_usize()函数设置一个窗口的初始化大小。窗口位置指的是窗口的左上顶点到屏幕左边和顶边的距离,可以用gtk_widget_set_uposition()函数来设置一个窗口的初始位置。这两个函数的原型为:

void gtk_widget_set_usize(GtkWidget *widget, gint width, gint height);

void gtk_widget_set_uposition(GtkWidget *widget, gint x, gint y);

参数widget用于指定将要进行设置的窗口,width表示窗口的宽度,height表示窗口的高度;x表示窗口的左边距,即左上顶点的x坐标,y表示窗口的上边距,也是窗口的左上顶点的y坐标。

显示窗口需要调用gtk_widget_show()函数。


标签

1.         新建标签

gtk_label_new()可以建立一个标签,函数原型如下:

GtkWidget * gtk_label_new (gchar *text);

返回:若成功则返回GtkWidget类型的指针,失败则返回NULL。

参数text表示标签需要显示的内容

2.         将标签添加到窗口

GTK+窗口中,除了window窗口外,其他元件都必须放置在一个容器中。新建的标签并不能直接显示,需要放在一个窗口元件中。gtk_container_add()函数作用是把一个元件放置在另一个元件窗口(窗口)中,函数原型如下:

void gtk_container_add (GtkContainer *container, GtkWidget *widget);

参数container是一个父级容器指针,widget是需要放置的元件指针。

3.         设置与获取标签文本

在程序中,可以用gtk_label_get_text()函数获取一个标签的文本。使用gtk_label_set_text()函数来设置一个标签的文本。这两个函数的原型为:

const char* gtk_label_get_text (GtkLabel *label);

void gtk_label_set_text (GtkLabel *label, gchar *text);

第一个函数返回:若成功则返回标签文本的字符串指针,失败则返回NULL。

函数中参数label是一个指向标签的指针,text表示标签需要设置的文本。

显示标签需要调用gtk_widget_show()函数


按钮

1.         新建按钮

gtk_button_new_with_label()可以建立一个带标签的按钮,函数原型如下:

GtkWidget * gtk_button_new_with_label (gchar *label);

返回:若成功则返回GtkWidget类型的指针,失败则返回NULL。

参数label表示按钮需要显示的内容

2.         设置与获取按钮的标签

gtk_button_get_label()函数可以获取一个按钮的标签。gtk_button_set_label()函数可以设置一个按钮的标签。这两个函数的原型为:

const gchar* gtk_button_get_label (GtkButton *button);

void gtk_button_set_label (GtkButton *button, const gchar *label);

第一个函数返回:若成功则返回按钮标签内容的字符串指针,失败则返回NULL。

函数中参数button是一个指向按钮的指针,label表示按钮的标签内容。按钮的使用通常伴随着GTK+信号与事件的产生。

显示按钮需要调用gtk_widget_show()函数

  


文本框

1.         新建文本框

gtk_entry_new()可以建立一个文本框,函数原型如下:

GtkWidget * gtk_entry_new (void);

返回:若成功则返回GtkWidget类型的指针,失败则返回NULL。

另一个建立文本框的函数为:

GtkWidget * gtk_entry_new_with_max_length (gint max);

返回同上,参数max用来表示这个文本框最多可以输入的字节数。

2.         设置与获取文本框数据

gtk_entry_get_text()函数gtk_entry_set_text()函数可以得到和设置文本框的数据。这两个函数的原型为:

const gchar* gtk_entry_get_text (GtkEntry *entry);

void gtk_entry_set_text (GtkEntry *entry, const gchar *text);

第一个函数返回:若成功则返回按钮标签内容的字符串指针,失败则返回NULL。

函数中参数entry是一个指向文本框的指针,text表示设置到文本框中的字符串文本。

显示文本框需要调用gtk_widget_show()函数

example: 保存为entry_example.c

 1 #include <gtk/gtk.h>
 2 #include <stdlib.h>
 3  
 4  
 5  GtkWidget *window;
 6  GtkWidget *table;
 7  GtkWidget *entry;
 8  GtkWidget *label;
 9  GtkWidget *button;
10  char text[50];
11 
12 void on_clicked(GtkWidget *widget, gpointer data)
13 {
14   strcpy(text, gtk_entry_get_text (GTK_ENTRY(entry)));
15   printf("您输入到字符串是:%s:\n",text);
16 }
17 
18  int main(int argc, char* argv[])
19  {
20      gtk_init(&argc, &argv);
21      window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
22      //设置窗口标题
23      gtk_window_set_title(GTK_WINDOW(window), g_locale_to_utf8("文本框的使用", -1, NULL, NULL, NULL));
24      //定义3行2列的表格,单元格大小根据单元格元件大小自动调整
25      table = gtk_table_new(3, 2, FALSE);
26      label = gtk_label_new(g_locale_to_utf8("请在这里输入文本", -1, NULL, NULL, NULL));
27      //新建有字数限制的文本框,最多输入50个字符
28      entry = gtk_entry_new_with_max_length(50);
29      //新建提交按钮
30      button = gtk_button_new_with_label(g_locale_to_utf8("提交", -1, NULL, NULL, NULL));
31      //将表格添加到窗口中
32      gtk_container_add(GTK_CONTAINER(window), table);
33      //将三个元件分别添加到表格相应的位置
34      gtk_table_attach (GTK_TABLE(table), label, 0, 1, 0, 1, 
35              (GtkAttachOptions)(0), (GtkAttachOptions)(0), 10, 10);
36      gtk_table_attach (GTK_TABLE(table), entry, 0, 2, 1, 2, 
37          (GtkAttachOptions)(0), (GtkAttachOptions)(0), 10, 10);
38      gtk_table_attach (GTK_TABLE(table), button, 1, 2, 2, 3, 
39          (GtkAttachOptions)(0), (GtkAttachOptions)(0), 10, 10);
40      g_signal_connect (G_OBJECT(button), "clicked", G_CALLBACK(on_clicked), window);
41      gtk_widget_show_all(window);
42      gtk_main();    
43      return 0;
44  }

 使用gcc编译

gcc -o entry_example entry_example.c `pkg-config --libs --cflags gtk+-2.0`

./entry_example

运行结果为

在文本框中输入"hello world!"并点击提交,会在shell中显示

 


界面布局元件

GTK+的容器都是二进制的,也就是说每个容器只能放置一个元件,如果想在一个窗口中放置多个元件,则需要使用表格、窗格等有多个单元格的容器。

表格

1.表格的建立

在窗口中使用表格,需要调用gtk_table_new()函数新建一个表格,函数原型如下:

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

返回:若成功则返回一个GtkWidget类型的指针,失败则放回NULL

参数rows表示表格的行数,columns表示表格列数,类型是无符号整型。行列标号从边开始算起,如下图所示

例如,某个元件占据了上图蓝色阴影部分,则它所占格子的坐标为left0, right2, top2, butoom4

参数homogeneous是一个布尔值,TRUE表示每个单元格大小相同,所有单元格高度和宽度和表格中最大的一个相同;FALSE表示单元格大小会根据元件大小自动调整。

表格的作用只是将窗口划分成不同的区域,并不能显示出这个表格。


函数gtk_table_attach()作用是将一个元件添加到表格中,并设置在表格的位置和填充的选项。函数原型如下:

void gtk_table_attach(GtkTable *table, GtkWidget *child, guint left_attach, guint right_attach, guint top_attach, guint buttom_attach,

GtkAttachOptions xoptions, GtkAttachOptions yoptions,

guint xpadding, guint ypadding);

参数含义和作用:

  • table:容器表格的指针。
  • child:需要添加的元件的指针。
  • left_attachright_attach:分别表示元件的左边是表格x方向的第几条边,右边是表格x方向的第几条边。
  • top_attach, buttom_attach:分别表示元件的上边是表格y方向的第几条边,下边是表格y方向的第几条边。
  • xoptionsyoptions:分别表示元件在表格中的水平方向、垂直方向的对齐方式,取值类型为GtkAttachOptions
  • xpaddingypadding:分别表示元件与边框水平方向、垂直方向的边距。


表格可以嵌套表格。

下面为程序演示例子,保存为con_nested_table.c

 1 #include<gtk/gtk.h>
 2 
 3 int main(int argc, char *argv[])
 4 {
 5     GtkWidget *window;
 6     GtkWidget *table1;
 7     GtkWidget *table2;
 8     GtkWidget *button1;
 9     GtkWidget *button2;
10     GtkWidget *entry1;
11     GtkWidget *entry2;
12     GtkWidget *entry3;
13     GtkWidget *entry4;
14     GtkWidget *label1;
15     GtkWidget *label2;
16     GtkWidget *label3;
17     GtkWidget *label4;
18     GtkWidget *label5;
19     
20     gtk_init(&argc, &argv);
21     window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
22     gtk_window_set_title (GTK_WINDOW (window), g_locale_to_utf8("用户信息", -1, NULL, NULL, NULL));//设置窗口标题
23     //建立表格
24     table1 = gtk_table_new (4, 4, FALSE);
25     table2 = gtk_table_new (1, 2, FALSE);
26     //定义5个标签、2个按钮、4个文本框
27     label1 = gtk_label_new (g_locale_to_utf8("我的信息", -1, NULL, NULL, NULL));
28     label2 = gtk_label_new (g_locale_to_utf8("用户名", -1, NULL, NULL, NULL));
29     label3 = gtk_label_new (g_locale_to_utf8("密码", -1, NULL, NULL, NULL));
30     label4 = gtk_label_new (g_locale_to_utf8("电子邮件", -1, NULL, NULL, NULL));
31     label5 = gtk_label_new (g_locale_to_utf8("详细地址", -1, NULL, NULL, NULL));
32     button1 = gtk_button_new_with_label(g_locale_to_utf8("注册", -1, NULL, NULL, NULL));
33     button2 = gtk_button_new_with_label(g_locale_to_utf8("登录", -1, NULL, NULL, NULL));
34     entry1 = gtk_entry_new ();
35     entry2 = gtk_entry_new ();
36     entry3 = gtk_entry_new ();
37     entry4 = gtk_entry_new ();
38     //添加表格到窗口
39     gtk_container_add(GTK_CONTAINER (window), table1);
40     //将5个元件分别添加到表格中
41     gtk_table_attach (GTK_TABLE(table1), label1, 0, 3, 0, 1,
42                  (GtkAttachOptions)(0), (GtkAttachOptions)(0), 5, 5);
43     gtk_table_attach (GTK_TABLE(table1), table2, 3, 4, 0, 1,
44                  (GtkAttachOptions)(0), (GtkAttachOptions)(0), 0, 5);
45     gtk_table_attach (GTK_TABLE(table1), label2, 0, 1, 1, 2,
46                  (GtkAttachOptions)(0), (GtkAttachOptions)(0), 5, 5);
47     gtk_table_attach (GTK_TABLE(table1), entry1, 1, 2, 1, 2,
48                  (GtkAttachOptions)(0), (GtkAttachOptions)(0), 5, 5);
49     gtk_table_attach (GTK_TABLE(table1), label3, 2, 3, 1, 2,
50                  (GtkAttachOptions)(0), (GtkAttachOptions)(0), 5, 5);
51     gtk_table_attach (GTK_TABLE(table1), entry2, 3, 4, 1, 2,
52                  (GtkAttachOptions)(0), (GtkAttachOptions)(0), 5, 5);
53     gtk_table_attach (GTK_TABLE(table1), label4, 0, 1, 2, 3,
54                  (GtkAttachOptions)(0), (GtkAttachOptions)(0), 5, 5);
55     gtk_table_attach (GTK_TABLE(table1), entry3, 1, 4, 2, 3,
56                  (GtkAttachOptions)(0), (GtkAttachOptions)(0), 5, 5);
57     gtk_table_attach (GTK_TABLE(table1), label5, 0, 1, 3, 4,
58                  (GtkAttachOptions)(0), (GtkAttachOptions)(0), 5, 5);
59     gtk_table_attach (GTK_TABLE(table1), entry4, 1, 4, 3, 4,
60                  (GtkAttachOptions)(0), (GtkAttachOptions)(0), 5, 5);
61     gtk_table_attach (GTK_TABLE(table2), button1, 0, 1, 0, 1,
62                  (GtkAttachOptions)(0), (GtkAttachOptions)(0), 2, 5);
63     gtk_table_attach (GTK_TABLE(table2), button2, 1, 2, 0, 1,
64                  (GtkAttachOptions)(0), (GtkAttachOptions)(0), 2, 5);
65     gtk_widget_show_all(window);
66     gtk_main();
67     return 0;      
68                  
69                  
70     }

使用GCC编译

gcc -o con_nested_table con_nested_table.c `pkg-config --libs --cflags gtk+-2.0`

./con_nested_table

 运行结果为


框(box)是一種不可見的widget容器。框分为纵向框和横向框。纵向框在垂直方向堆积元件,横向框沿水平方向堆积元件。

1.框的建立
使用gtk_vbox_new函数建立纵向框,使用gtk_hbox_new函数建立横向框。函數原型爲:

GtkWidget *gtk_hbox_new(gboolean homogeneous,gint spacing);
GtkWidget *gtk_vbox_new(gboolean homogeneous,gint spacing);

参数:

  • homogeneous子构件是否具有同样的大小
  • spacing 子构件间的距离

建立框後,需要調用gtk_container_add()函數將這個框添加到窗口中。

2.框中添加元件

可以使用gtk_box_pack_start函数或gtk_box_pack_end函数将构件放到组装盒中。前者從左到右、從上到下將元件放入框容器,而後者從右到左,從下到上將元件放入框容器。其原型爲:

void gtk_box_pack_start(GtkBox *box, GtkWidget *child, gboolean expend, gboolean fill, guint padding);
void gtk_box_pack_end(GtkBox *box, GtkWidget *child, gboolean expend, gboolean fill, guint padding);

 

参数:

  • box:框的名称
  • child子构件的名称
  • expend构件周围是否还有可扩充的空间
  • fill构件是否需要充分利用构件周围空间
  • padding构件周围要保留多少个填充的像元

下面是使用垂直框的程序例子,保存爲vbox_example.c

 1 #include<gtk/gtk.h>
 2     GtkWidget *window;
 3     GtkWidget *table;
 4     GtkWidget *vbox;
 5     GtkWidget *button;
 6     GtkWidget *label;
 7     GtkWidget *entry;
 8     char text[50];
 9     char text1[50];
10     char a[50];
11     int i = 0;
12     
13 //定义信号回调函数
14 void on_clicked(GtkWidget *widget, gpointer data)
15 {
16     ++i;
17     gcvt((float)i, 3, text);
18     strcat(text, ":");
19     //获取文本框内容,并将其复制到text字符串数组中
20     strcpy(text1, gtk_entry_get_text(GTK_ENTRY(entry)));
21     strcat(text, text1);
22     strcat(a, "\n");
23     strcat(a, text);
24     gtk_label_set_text(GTK_LABEL(label), a);
25 }
26 
27 int main(int argc, char *argv[])
28 {
29         
30     gtk_init(&argc, &argv);
31     window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
32     gtk_window_set_title (GTK_WINDOW (window), g_locale_to_utf8("我也来评论", -1, NULL, NULL, NULL));//设置窗口标题
33     //设置窗口边框
34     gtk_container_border_width(GTK_CONTAINER(window), 5);
35     vbox = gtk_vbox_new (FALSE, 10);
36     //建立表格    
37     table = gtk_table_new (2, 2, FALSE);
38     //定义标签、按钮、文本框
39     label = gtk_label_new (g_locale_to_utf8("评论内容", -1, NULL, NULL, NULL));
40     
41     button = gtk_button_new_with_label(g_locale_to_utf8("发表评论", -1, NULL, NULL, NULL));
42     
43     entry = gtk_entry_new ();
44     //添加表格到窗口
45     gtk_container_add(GTK_CONTAINER (window), vbox);
46     gtk_box_pack_start (GTK_BOX(vbox), label, TRUE, FALSE, 5);
47     gtk_box_pack_start (GTK_BOX(vbox), table, TRUE, FALSE, 5);
48     //将元件分别添加到表格中
49     gtk_table_attach (GTK_TABLE(table), entry, 0, 2, 0, 1,
50                  (GtkAttachOptions)(0), (GtkAttachOptions)(0), 5, 5);
51     gtk_table_attach (GTK_TABLE(table), button, 1, 2, 1, 2,
52                  (GtkAttachOptions)(0), (GtkAttachOptions)(0), 0, 0);
53     g_signal_connect (G_OBJECT(button), "clicked", G_CALLBACK(on_clicked), window);
54     gtk_widget_show_all(window);
55     gtk_main();
56     return 0;                       
57     }

使用GCC编译

gcc -o vbox_example vbox_example.c `pkg-config --libs --cflags gtk+-2.0`

./vbox_example

 运行结果为

 


其他常用元件

1進度條、微調按鈕、組合框

1.1進度條

創建進度條要使用GtkAdjustment元件。gtk_adjustment_new()函數用於創建GtkAdjustment元件,函數原型如下:

GtkObject* gtk_adjustment_new (gdouble initial_value, gdouble lower_range, gdouble upper_range, 

               gdouble step_increment, gdouble page_increment, gdouble page_size);


初始化新的调节设置对象需要6个参数。下面列出参数列表。

  • initial_value:当初始化时,调节设置对象中存储的值。
  • lower_range:调节设置对象允许的最小值。
  • upper_range:调节设置对象允许的最大值。
  • step_increment:当鼠标左鍵按下時元件一次增加/減少的值。
  • page_increment: 当鼠标右鍵按下時元件一次增加/減少的值
  • page_size:页的大小。这个值对于GtkSpinButton没什么用处,因此它总是被设置成为和page_increment同样的值,或者0


GTK+中创建进度条的函数调用有兩個,函數原型如下:

GtkWidget *gtk_progress_bar_new(void);

GtkWidget *gtk_progress_bar_new_with_adjustment(GtkAdjustment *adjustmen);


gtk_progress_bar_set_bar_style()函数用于设置进度条的样式,函数原型如下:

gtk_progress_bar_set_bar_style(GtkProgressBar *pbar, GtkProgressBarStyle style);

参数pbar是一个指向进度条的指針,style表示进度条的样式,取值如下:

  • GTK_PROGRESS_CONTINUOUS:连续进度条
  • GTK_PROGRESS_DISCRETE:条块进度条


gtk_progress_bar_set_orientation()函数用于设置进度条的方向,函数原型如下:

gtk_progress_bar_set_orientation(GtkProgressBar *pbar, GtkProgressBarOrientation orentation);

参数pbar是一个指向进度条的指針,orientation表示进度条的方向,取值如下:

  • GTK_PROGRESS_LEFT_TO_RIGHT:从左往右显示
  • GTK_PROGRESS_RIGHT_TO_LEFT:从右往左显示
  • GTK_PROGRESS_BOTTOM_TO_TOP:从下往上显示
  • GTK_PROGRESS_TOP_TO_BOTTOM:从上往下显示


gtk_progress_bar_update()函数用于更新进度条的进度状态,函数原型如下:

void gtk_progress_bar_update(GtkProgressBar *pbar, gfloat percentage);

参数pbar是一个指向进度条的指針,percentage表示进度条进度状态



1.2微调按钮

gtk_spin_button_new()用于创建微调按钮,函数原型如下:

GtkWidget *gtk_spin_button_new (GtkAdjustment *adjustment, gdouble climb_rate, guint digits);

参数climb_rate 表示微调按钮每步增加或减少的量,digits表示包含 的小数位数。


还可以使用相关的函数条用获取和设置微调按钮的值。

gtk_spin_button_get_value_as_float() 用于获取微调按钮的值,而gtk_spin_button_set_value()用于设置微调按钮的值,函数原型如下:

gtk_spin_button_get_value_as_float(GtkSpinButton *spin_button);

gtk_spin_button_set_value(GtkSpinButton *spin_button, gfloat value);

 

1.3组合框

组合框是文本框和列表框的组合,也称下拉列表。创建组合框要使用GList元件,用于保存列表框中将要显示的字符串。g_list_append()函数用于向GList中添加字符串,函数原型如下:

GList *g_list_append(GList *glist, char *string);

参数glist是一个指向列表框的指针,string指向将要添加至列表框中的字符串。


gtk_combo_new()函数用于创建一个组合框,函数原型如下:

GtkWidget *gtk_combo_new(void);


gtk_combo_set_popdown_strings()函数用于设置组合框中显示的字符串,函数原型如下:

gtk_combo_set_popdown_strings( GtkCombo *combo, GList *strings);

参数combo是一个指向组合框的指针,strings表示组合框中将要显示的字符串。


下面给出一个进度条、微调按钮和组合框的示例程序。control_example.c

 1 #include<gtk/gtk.h>
 2 
 3 int main(int argc, char *argv[])
 4 {
 5     GtkWidget *window;
 6     GtkWidget *vbox;    
 7     GtkWidget *label1;
 8     GtkWidget *label2;
 9     GtkWidget *label3;
10     GtkWidget *bar;
11     GtkWidget *spinbutton;
12     GtkObject *adjustment;
13     GList *glist;
14     GtkWidget *combo;
15     
16     gtk_init(&argc, &argv);
17     window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
18     gtk_window_set_title (GTK_WINDOW (window), g_locale_to_utf8("控制元件", -1, NULL, NULL, NULL));//设置窗口标题
19     //设置窗口边框宽度30
20     gtk_container_border_width(GTK_CONTAINER(window), 30);
21     //创建垂直框
22     vbox = gtk_vbox_new(FALSE, 0);
23     gtk_container_add(GTK_CONTAINER(window), vbox);
24     
25     //新建标签1
26     label1 = gtk_label_new (g_locale_to_utf8("进度条", -1, NULL, NULL, NULL));
27     //将标签添加到垂直框
28     gtk_box_pack_start(GTK_BOX(vbox), label1, TRUE, TRUE, 0);
29     //创建进度条
30     adjustment = gtk_adjustment_new(70.0, 0.0, 100.0, 1.0, 0.0, 0.0);
31     bar = gtk_progress_bar_new_with_adjustment(GTK_ADJUSTMENT(adjustment));
32     gtk_progress_bar_set_bar_style(GTK_PROGRESS_BAR(bar), GTK_PROGRESS_CONTINUOUS);
33     gtk_progress_bar_set_orientation(GTK_PROGRESS_BAR(bar), GTK_PROGRESS_LEFT_TO_RIGHT);
34     //将进度条添加到垂直框
35     gtk_box_pack_start(GTK_BOX(vbox), bar, TRUE, TRUE, 15);
36 
37     //新建标签2
38     label2 = gtk_label_new (g_locale_to_utf8("微调按钮", -1, NULL, NULL, NULL));
39     //将标签添加到垂直框
40     gtk_box_pack_start(GTK_BOX(vbox), label2, TRUE, TRUE, 0);
41     //创建微调按钮
42     adjustment = gtk_adjustment_new(80.0, 0.0, 100.0, 1.0, 0.0, 0.0);    
43     spinbutton = gtk_spin_button_new(GTK_ADJUSTMENT(adjustment), 1.0, 1);
44     //将微调按钮添加到垂直框
45     gtk_box_pack_start(GTK_BOX(vbox), spinbutton, TRUE, TRUE, 15);
46     
47     //新建标签3
48     label3 = gtk_label_new (g_locale_to_utf8("下拉列表", -1, NULL, NULL, NULL));
49     //将标签添加到垂直框
50     gtk_box_pack_start(GTK_BOX(vbox), label3, TRUE, TRUE, 0);
51     //创建组合框
52     glist = NULL;
53     glist = g_list_append(glist, "banana");
54     glist = g_list_append(glist, "apple");
55     glist = g_list_append(glist, "orange");
56     glist = g_list_append(glist, "pear");
57     glist = g_list_append(glist, "strawberry");
58     combo = gtk_combo_new();
59     gtk_combo_set_popdown_strings(GTK_COMBO(combo), glist);
60     //将组合框添加到垂直框
61     gtk_box_pack_start(GTK_BOX(vbox), combo, TRUE, TRUE, 15);
62     gtk_widget_show_all(window);
63     gtk_main();
64     return 0;                   
65                  
66     }

使用GCC编译

gcc -o control_example control_example.c `pkg-config --libs --cflags gtk+-2.0`

./control_example

 运行结果为

2单选按钮(radio)、复选按钮(check)


创建单选按钮函数有两个,原型如下:

GtkWidget *gtk_radio_button_new(GSList *group);

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

 

创建复选按钮函数也有两个,原型如下:

GtkWidget *gtk_check_button_new(void);

GtkWidget *gtk_check_button_new_with_label( gchar *label);

 

第一个函数创建无标签按钮,第二个函数用于创建带有文本标签的按钮。


下面给出一个程序例子, check_radio.c

注意:生产第一个radio按钮时,group参数为NULL,而以后每次在该组创建一个radio按钮时都要使用gtk_radio_button_group函数获得新的group


 1 #include<gtk/gtk.h>
 2 
 3 int main(int argc, char *argv[])
 4 {
 5     GtkWidget *window;
 6     GtkWidget *table;
 7     GtkWidget *label1;
 8     GtkWidget *label2;
 9     GSList *group;
10     GtkWidget *check;
11     GtkWidget *radio;
12         
13     gtk_init(&argc, &argv);
14     window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
15     gtk_window_set_title (GTK_WINDOW (window), g_locale_to_utf8("单选、复选按钮", -1, NULL, NULL, NULL));//设置窗口标题
16     //设置窗口边框宽度15
17     gtk_container_border_width(GTK_CONTAINER(window), 15);
18     //建立表格
19     table = gtk_table_new (4, 4, FALSE);
20     //定义标签
21     label1 = gtk_label_new (g_locale_to_utf8("业余时间活动爱好", -1, NULL, NULL, NULL));
22     label2 = gtk_label_new (g_locale_to_utf8("平时每天学习时间", -1, NULL, NULL, NULL));
23     
24     //添加表格到窗口
25     gtk_container_add(GTK_CONTAINER (window), table);
26     //将元件分别添加到表格中
27     gtk_table_attach (GTK_TABLE(table), label1, 0, 2, 0, 1,
28                  (GtkAttachOptions)(0), (GtkAttachOptions)(0), 0, 0);
29     
30     gtk_table_attach (GTK_TABLE(table), label2, 0, 2, 2, 3,
31                  (GtkAttachOptions)(0), (GtkAttachOptions)(0), 0, 5);
32     //生成四个check按钮,分别添加到表格中
33     check = gtk_check_button_new_with_label(g_locale_to_utf8("篮球", -1, NULL, NULL, NULL));
34     gtk_table_attach(GTK_TABLE(table), check, 0, 1, 1, 2,
35                  (GtkAttachOptions)(0), (GtkAttachOptions)(0), 5, 10);
36                  
37     check = gtk_check_button_new_with_label(g_locale_to_utf8("足球", -1, NULL, NULL, NULL));
38     gtk_table_attach(GTK_TABLE(table), check, 1, 2, 1, 2,
39                  (GtkAttachOptions)(0), (GtkAttachOptions)(0), 5, 10); 
40                              
41     check = gtk_check_button_new_with_label(g_locale_to_utf8("爬山", -1, NULL, NULL, NULL));
42     gtk_table_attach(GTK_TABLE(table), check, 2, 3, 1, 2,
43                  (GtkAttachOptions)(0), (GtkAttachOptions)(0), 5, 10);
44                  
45     check = gtk_check_button_new_with_label(g_locale_to_utf8("郊游", -1, NULL, NULL, NULL));
46     gtk_table_attach(GTK_TABLE(table), check, 3, 4, 1, 2,
47                  (GtkAttachOptions)(0), (GtkAttachOptions)(0), 5, 10);
48     
49     //生成四个radio按钮,分别添加到表格中,注意:生产第一个radio按钮时,group参数为NULL,
50     //而以后每次在该组创建一个radio按钮时都要使用gtk_radio_button_group函数获得新的group值
51     radio = gtk_radio_button_new_with_label(NULL, g_locale_to_utf8("3~4小时", -1, NULL, NULL, NULL));
52     gtk_table_attach(GTK_TABLE(table), radio, 0, 1, 3, 4,
53                  (GtkAttachOptions)(0), (GtkAttachOptions)(0), 5, 5);
54                  
55     group = gtk_radio_button_group(GTK_RADIO_BUTTON(radio));             
56     radio = gtk_radio_button_new_with_label(group, g_locale_to_utf8("4~5小时", -1, NULL, NULL, NULL)); 
57     gtk_table_attach(GTK_TABLE(table), radio, 1, 2, 3, 4,
58                  (GtkAttachOptions)(0), (GtkAttachOptions)(0), 5, 5);
59                  
60     group = gtk_radio_button_group(GTK_RADIO_BUTTON(radio));               
61     radio = gtk_radio_button_new_with_label(group, g_locale_to_utf8("5~6小时", -1, NULL, NULL, NULL));
62     gtk_table_attach(GTK_TABLE(table), radio, 2, 3, 3, 4,
63                  (GtkAttachOptions)(0), (GtkAttachOptions)(0), 5, 5);
64                  
65     group = gtk_radio_button_group(GTK_RADIO_BUTTON(radio));  
66     radio = gtk_radio_button_new_with_label(group, g_locale_to_utf8(">=6小时", -1, NULL, NULL, NULL));
67     gtk_table_attach(GTK_TABLE(table), radio, 3, 4, 3, 4,
68                  (GtkAttachOptions)(0), (GtkAttachOptions)(0), 5, 5);             
69                              
70     gtk_widget_show_all(window);
71     gtk_main();
72     return 0;      
73                  
74                  
75     }

使用GCC编译

gcc -o check_radio check_radio.c `pkg-config --libs --cflags gtk+-2.0`

./check_radio

 运行结果为

 

3下拉菜单


创建菜单的函数有两个,函数原型如下:

GtkWidget *gtk_menu_new();

GtkWidget *gtk_menu_new_with_label(gchar *label);

第一个函数创建无标签菜单,第二个函数用于创建带有文本标签的菜单。


创建菜单项的函数类似于创建菜单,函数原型如下:

GtkWidget *gtk_menu_item_new();

GtkWidget *gtk_menu_item_new_with_label(gchar *label);


插入菜单项的函数原型如下:

void gtk_menu_append (GtkMenu *menu, GtkWidget *child);

void gtk_menu_item_set_submenu (GtkMenuItem item, GtkMenu *menu);


创建菜单条函数原型如下:

GtkWidget *gtk_menu_bar_new(void);

向菜单条中加入菜单

void gtk_menu_bar_append (GtkMenuBar *bar, GtkWidget *child);


创建菜单的步骤如下:

  • 使用gtk_menu_new()生成一个新菜单。
  • 使用gtk_menu_item_new() gtk_menu_item_new_with_label()生成一个新的菜单项,然后使用 gtk_menu_item_append()将每一个菜单项加入到菜单中,使用 gtk_menu_item_new ()gtk_menu_item_new_with_label()创建主菜单项。
  • 使用 gtk_menu_item_set_submenu ()将各个菜单加入到主菜单项中。
  • 使用gtk_menu_bar_new()创建菜单条,这一步仅需做一次。然后使用 gtk_menu_bar_append 把主菜单项加入到菜单条上。

 下面是程序例子,menu_example.c

 1 #include<gtk/gtk.h>
 2 
 3 int main(int argc, char *argv[])
 4 {
 5     GtkWidget *window;
 6     GtkWidget *menu;
 7     GtkWidget *menubar;
 8     GtkWidget *rootmenu;
 9     GtkWidget *menuitem;
10         
11     gtk_init(&argc, &argv);
12     window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
13     gtk_window_set_title (GTK_WINDOW (window), g_locale_to_utf8("下拉菜单", -1, NULL, NULL, NULL));//设置窗口标题
14     gtk_widget_set_usize(window, 200, 40);
15     //创建新菜单,然后创建3个菜单项,并把菜单项加入到菜单中
16     
17     menu = gtk_menu_new();
18     menuitem = gtk_menu_item_new_with_label(g_locale_to_utf8("新建", -1, NULL, NULL, NULL));
19     gtk_menu_append(GTK_MENU(menu), menuitem);
20     
21     menuitem = gtk_menu_item_new_with_label(g_locale_to_utf8("打开", -1, NULL, NULL, NULL));
22     gtk_menu_append(GTK_MENU(menu), menuitem);
23     
24     menuitem = gtk_menu_item_new_with_label(g_locale_to_utf8("关闭", -1, NULL, NULL, NULL));
25     gtk_menu_append(GTK_MENU(menu), menuitem);
26     
27     menuitem = gtk_menu_item_new_with_label(g_locale_to_utf8("保存", -1, NULL, NULL, NULL));
28     gtk_menu_append(GTK_MENU(menu), menuitem);
29     
30     //创建一个主菜单
31     rootmenu = gtk_menu_item_new_with_label(g_locale_to_utf8("文件", -1, NULL, NULL, NULL));
32     //将菜单加入到主菜单中
33     gtk_menu_item_set_submenu(GTK_MENU_ITEM(rootmenu), menu);
34     
35     //创建菜单条
36     menubar = gtk_menu_bar_new();
37     //将主菜单项加入到菜单条
38     gtk_menu_bar_append(GTK_MENU_BAR(menubar), rootmenu);
39     
40     //下面创建第二组菜单
41     menu = gtk_menu_new();
42     menuitem = gtk_menu_item_new_with_label(g_locale_to_utf8("复制", -1, NULL, NULL, NULL));
43     gtk_menu_append(GTK_MENU(menu), menuitem);
44     
45     menuitem = gtk_menu_item_new_with_label(g_locale_to_utf8("剪切", -1, NULL, NULL, NULL));
46     gtk_menu_append(GTK_MENU(menu), menuitem);
47     
48     menuitem = gtk_menu_item_new_with_label(g_locale_to_utf8("粘贴", -1, NULL, NULL, NULL));
49     gtk_menu_append(GTK_MENU(menu), menuitem);
50     
51     menuitem = gtk_menu_item_new_with_label(g_locale_to_utf8("删除", -1, NULL, NULL, NULL));
52     gtk_menu_append(GTK_MENU(menu), menuitem);
53     
54     rootmenu = gtk_menu_item_new_with_label(g_locale_to_utf8("编辑", -1, NULL, NULL, NULL));
55     //将菜单加入到主菜单中
56     gtk_menu_item_set_submenu(GTK_MENU_ITEM(rootmenu), menu);      
57     
58     gtk_menu_bar_append(GTK_MENU_BAR(menubar), rootmenu);
59     //将菜单条加入到窗口中
60     gtk_container_add(GTK_CONTAINER(window), menubar);
61                              
62     gtk_widget_show_all(window);
63     gtk_main();
64     return 0;      
65                  
66                  
67     }

使用GCC编译

gcc -o menu_example menu_example.c `pkg-config --libs --cflags gtk+-2.0`

./menu_example

 运行结果为

 

 下拉菜单截图工具截不出来。。


信号与回调函数

图形用户界面的程序是事件驱动的程序。程序进入gtk_ain()函数后,等待事件的发生,一旦发生某个事件,相应的信号将产生。如果程序中定义了相应的消息处理函数(也称回调函数),系统将自动进行调用。


1添加信号

信号的作用是对某个元件添加一个用户交互的功能。函数g_signal_connect() 可以把一个信号处理函数(或称回调函数)添加到一个元件上,在元件和消息处理函数间建立关联,该函数原型如下:

gulong g_signal_connect (GtkObject *object, ghar *name,

Gcallback callback_func, gpointer func_data);

参数object是一个元件的指针,指向将产生信号的元件;name表示消息或事件的类型,

一个按钮所有的事件类型与含义如下:

  • activate:激活的时候发生
  • clicked:单击以后发生
  • enter:鼠标指针进入这个按钮以后发生
  • leave:鼠标指针离开这个按钮以后发生
  • pressed:鼠标按下以后发生
  • released:鼠标释放以后发生


参数callback_func表示信号产生后将要执行的回调函数,func_data为传递给回调函数的数据,与callback_func函数的第二个参数相同

g_signal_connect函数中,使用事件的不同名称来区分不同的事件(即第二个参数name)。


2回调函数

消息处理函数(回调函数)原型如下:

void callback_func (GtkWidget *widget, gpointer func_data);

参数widget指向要接收消息的元件,参数 func_data指向消息产生时传递给该函数的数据。

程序例子 signal_example.c

 1 #include<gtk/gtk.h>
 2     
 3     GtkWidget *window;
 4     GtkWidget *table;
 5     GtkWidget *button;
 6     GtkWidget *label1;
 7     GtkWidget *label2;
 8     GtkWidget *label3;
 9     int i = 0;
10     
11 //定义信号回调函数
12 void on_clicked(GtkWidget *widget, gpointer data)
13 {
14     char a[20];
15     ++i;
16     gcvt((float)i, 3, a);
17     
18     gtk_label_set_text(GTK_LABEL(label2), a);
19 }
20 
21 int main(int argc, char *argv[])
22 {
23         
24     gtk_init(&argc, &argv);
25     window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
26     gtk_window_set_title (GTK_WINDOW (window), g_locale_to_utf8("信号与事件", -1, NULL, NULL, NULL));//设置窗口标题
27     //设置窗口边框
28     gtk_container_border_width(GTK_CONTAINER(window), 5);
29     
30     //建立表格    
31     table = gtk_table_new (2, 3, FALSE);
32     //定义标签、按钮
33     label1 = gtk_label_new (g_locale_to_utf8("点击按钮第", -1, NULL, NULL, NULL));
34     label2 = gtk_label_new (g_locale_to_utf8("0", -1, NULL, NULL, NULL));
35     label3 = gtk_label_new (g_locale_to_utf8("", -1, NULL, NULL, NULL));
36     button = gtk_button_new_with_label(g_locale_to_utf8("计数", -1, NULL, NULL, NULL));
37     
38     
39     //添加表格到窗口
40     gtk_container_add(GTK_CONTAINER (window), table);
41     
42     //将元件分别添加到表格中
43     gtk_table_attach (GTK_TABLE(table), label1, 0, 1, 0, 1,
44                  (GtkAttachOptions)(0), (GtkAttachOptions)(0), 0, 10);
45     gtk_table_attach (GTK_TABLE(table), label2, 1, 2, 0, 1,
46                  (GtkAttachOptions)(0), (GtkAttachOptions)(0), 0, 10);
47     gtk_table_attach (GTK_TABLE(table), label3, 2, 3, 0, 1,
48                  (GtkAttachOptions)(0), (GtkAttachOptions)(0), 0, 10);
49     gtk_table_attach (GTK_TABLE(table), button, 2, 3, 1, 2,
50                  (GtkAttachOptions)(0), (GtkAttachOptions)(0), 0, 10);             
51     g_signal_connect (G_OBJECT(button), "clicked", G_CALLBACK(on_clicked), window);
52     gtk_widget_show_all(window);
53     gtk_main();
54     return 0;                       
55     }

使用GCC编译

gcc -o signal_example signal_example.c `pkg-config --libs --cflags gtk+-2.0`

./signal_example

 运行结果为

The End!

不经历风雨,怎么见彩虹!
原文地址:https://www.cnblogs.com/ivorfeng/p/3096433.html