GTK+2.0编程范例代码分析-第一章(1)

本文通过几个示例介绍了GTK+2.0的基本用法,包括创建窗口、完善窗口功能、实现Hello程序以及使用盒状和格状容器排列按钮。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转载请注明:http://blog.youkuaiyun.com/hubbybob1/article/details/49159581
本文主要是针对 –GTK+2.0编程范例–宋国伟老师的书内的代码做一些注释,兼并讨论一下GTK+3.0与2.0的区别.其安装,在网上有很多讲解.
第1章 窗口与简单控件

1.1最简单的窗口
程序如下base.c

/*simple windows_base.c*/
#include <gtk/gtk.h>
int main(int argc,char*argv[])
{
    GtkWidget *window;//定义window控件
    gtk_init(&argc,&argv);//这句话是必须有的,初始化命令行参数

//创建window控件,参数GTK_WINDOW_TOPLEVEL:窗口类型,为最上层主窗口,GTK_WINDOW_TOPLEVEL:弹出式无边框窗口
    window=gtk_window_new(GTK_WINDOW_TOPLEVEL);

    gtk_widget_show(window);//创建后显示控件
    gtk_main();//这句话必须要,没有为什么,最关键,主事件循环
return 0;
}

下面是Makefile文件

CC=gcc
all:
    $(CC) -o base base.c `pkg-config --cflags --libs gtk+-2.0`

pkg-config –cflags –libs gtk+-2.0是指的向编译器指出包含文件的路径,动态链接库路径和要链接的动态链接库.此处的2.0可以换成3.0.执行make后运行base]文件如下:
这里写图片描述

1.2完善窗口功能
程序如下window.c

#include <gtk/gtk.h>
int main(int argc, char* argv[])
{
    GtkWidget *window;
    gtk_init(&argc,&argv);

    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);//GTK_WINDOW_POPUP创建窗口
    // g_signal_connect函数为glib函数包含四个参数
    //1:为链接的对象就是G_OBJECT,
    //2:信号名称,字符串形式,不同控件有不同信号,名称也不一样
    //3:回调函数,要使用G_CALLBACK来调用
    //4:传递个回调函数的参数,类型为gpointer,如果不是这个类型就强制转换,没有参数就是NULL
    //gtk_main_quit函数:退出主循环,就是借宿程序
    g_signal_connect(G_OBJECT(window),"delete_evernt",G_CALLBACK(gtk_main_quit),NULL);

    gtk_window_set_title(GTK_WINDOW(window),"一个完整的窗口");//设定窗口标题
    gtk_window_set_default_size(GTK_WINDOW(window),500,100);//设置窗口默认大小
    gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);
      //设置窗口位置:
      //GTK_WIN_POS_CENTER        居中
      //GTK_WIN_POS_NONE          不固定
      //GTK_WIN_POS_MOUSE         出现在鼠标位置
      //GTK_WIN_POS_CENTER_ALWAYS 窗口改变尺寸仍然居中
      //GTK_WIN_POS_CENTER_PARENT 居于父窗口中部

    gtk_widget_show(window);
    gtk_main();

    return FALSE;
}

其Makefile为:

CC = gcc
all:
    $(CC) -o window window.c `pkg-config --cflags --libs gtk+-2.0`

运行window后得到
这里写图片描述

1.3hello程序
程序hello.c如下:

//hello.c
#include <gtk/gtk.h>
gint count = 1;
void on_button_click(GtkWidget *button, gpointer userdata)// GtkWidget *button, int *userdata
{
    g_print("你好,这是hello功能的测试");
    g_print("%d   %d\n",(gint)userdata,count);//添加了count项
    count = count + 1;
}
int main(int argc, char* argv[])
{
    GtkWidget *window;
    GtkWidget *button;
    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_main_quit
    gtk_window_set_title(GTK_WINDOW(window),"hello test");
    gtk_window_set_default_size(GTK_WINDOW(window),500,100);
    gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);
    gtk_container_set_border_width(GTK_CONTAINER(window),60);
    //创建按钮
    button = gtk_button_new_with_label("按下此按钮会在终端显示信息");
   //为button添加一个回调函数为on_button_click,传入回调函数的参数为(gpointer)count
    g_signal_connect(G_OBJECT(button),"clicked",
                     G_CALLBACK(on_button_click),(gpointer)count);//(gpointer)count   (int)&(count) 
    gtk_container_add(GTK_CONTAINER(window),button);//把按钮加入窗口   

    gtk_widget_show(button);//显示按钮  ,这两个显示的顺序可以调换
    gtk_widget_show(window);//显示窗口
    gtk_main();

    return FALSE;

}//其Makefile如下:

CC = gcc
all:
    $(CC) -o hello hello.c `pkg-config --cflags --libs gtk+-2.0`

其显示的结果如下:
这里写图片描述
当按下按钮是产生的结果是,在终端打印出一下结果:
这里写图片描述
这个结果令我很失望,并不是书中所说的后面的回调函数执行后的值不断+1,而count却是不断加大的,这是为什么?我们来修改一些看看是什么样子:

/*把on_button_click回调函数修改为如下:参数gpointer userdata变为int *userdata*/
void on_button_click(GtkWidget *button, int *userdata)// GtkWidget *button, gpointer userdata
{    
    g_print("你好,这是hello功能的测试");
    i=*userdata;
    g_print("%d  %d\n",i,count);
    count = count + 1;
}

执行的结果为出现段错误:
这里写图片描述
那么继续修改主程序:


//g_signal_connect(G_OBJECT(button),"clicked",
//                 G_CALLBACK(on_button_click),(gpointer)count);//(gpointer)count   (gint)&(count)  
//把按钮回调函数修改为如下,把参数改为(gint)&(count)
  g_signal_connect(G_OBJECT(button),"clicked",
                   G_CALLBACK(on_button_click),(gint)&(count));//(gpointer)count   (gint)&(count)   

那么来编译一下,会出现如下提示:
这里写图片描述
就是说g_signal_connect的第四个参数需要gpointer指针,而我们传的却是int,但是没有报错,不管了直接运行,点击按钮看看结果如何:
这里写图片描述
可见无论是count的值,还是回调函数传过来的值都是变化的,那就改问了这是为什么呢,是BUG吗?,这个小编也不知道怎么回事,只能在以后的代码测试中来验证了.

1.4用盒状容器来排列按钮
程序pack.c如下:

/*容器主要包括:盒状容器(GtkBox),格状容器(GtkTable),按钮盒(GtkButtonBox),分割面板(GtkPanel),固定布局(GtkFixed),工具栏(GtkToolbar)等*/
/*用盒状容器排列按钮*/
#include <gtk/gtk.h>
int main(int argc,char* argv[])
{
    GtkWidget *window;
    GtkWidget *button;
    GtkWidget *box;//创建盒状容器
    gchar *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),title);//设置窗口标题
    gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);//设置窗口位置
    gtk_container_set_border_width(GTK_CONTAINER(window),20);

 //创建横向盒状容器
 //gtk_vbox_new(FALSE,0),这是创建竖向的,
 //第一个参数为是否均匀排放,FALSE:不均匀,有大有小,第二个参数表示容器中控件的间隔  
    box = gtk_hbox_new(FALSE,0);
    gtk_container_add(GTK_CONTAINER(window),box);//向window 内添加此容器
/**************************************************************
   1,把创建的button加入到容器内,可使用两种方法:使用gtk_container_add,但只能加1个控件,你可以下面的gtk_box_pack_start,换成gtk_box_pack_start,试试看,其实没什么变化,只是一些参数无法使用例如按钮间隔参数
   2,使用gtk_box_pack_*系列函数,这也有两种方法
      A.使用gtk_box_pack_start/gtk_box_pack_end,表示按顺序从前到后或者从后到前排列,含有5个参数
          容器GTK_BOX(box),
          控件对象指针button
          是否可扩展(就是横向是否可扩展,当横向拉大窗口时,其相对位置宽度都发生变化,当FASE就不变化,TRUE就变化)
          是否填充
          与前一控件的间隔
      B.使用gtk_box_pack_start_default/gtk_box_pack_end_default,只有两个参数,其他值都是默认
         但可以使用gtk_box_set_homogeneous/gtk_box_get_homogeneous设置/获得是否允许均匀排放
          可以使用gtk_box_set_spacing/gtk_box_get_spacing来设置/获得子空间之间的间隔
***************************************************************/
    button = gtk_button_new_with_label("按钮一");//创建button
    gtk_box_pack_start(GTK_BOX(box),button,TRUE,TRUE,3);
    //gtk_container_add(GTK_CONTAINER(box),button);

    button = gtk_button_new_with_label("按");
    gtk_box_pack_start(GTK_BOX(box),button,FALSE,FALSE,3);
   //gtk_container_add(GTK_CONTAINER(box),button);

    button = gtk_button_new_with_label("钮");
    gtk_box_pack_start(GTK_BOX(box),button,FALSE,FALSE,3);
    //gtk_container_add(GTK_CONTAINER(box),button);

    button = gtk_button_new_with_label("二");
   //gtk_container_add(GTK_CONTAINER(box),button);

    gtk_widget_show_all(window);//把六个gtk_widget_show()函数节省为1行,1个窗口,1个盒装容器,4个按钮
    gtk_main();
    return FALSE;
}//下面是Makefile
CC = gcc
all:
    $(CC) -o pack pack.c `pkg-config --cflags --libs gtk+-2.0`

这里写图片描述

1.5用格状容器来排列按钮
程序table.c如下:

/*格状容器 table.c*/
#include<gtk/gtk.h>
int main(int argc,char* argv[])
{
    GtkWidget * window;
    GtkWidget *table;
    GtkWidget *button;
    GtkWidget *frame;

    gtk_init(&argc,&argv);
  //创建窗口
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window),"格状容器");
    gtk_window_set_default_size(GTK_WINDOW(window),200,300);
    g_signal_connect(G_OBJECT(window),"delete_event",G_CALLBACK(gtk_main_quit),NULL);
    gtk_container_set_border_width(GTK_CONTAINER(window),20);
//创建框架控件
    frame=gtk_frame_new("请注意下面的按钮排列");
    gtk_container_add(GTK_CONTAINER(window),frame);//把frame添加到window内
//创建格装容器
    table = gtk_table_new(4,4,FALSE);//创建4行4列,不允许均匀排放
    gtk_container_set_border_width(GTK_CONTAINER(table),10);//设置格状容器的边线宽度为10
    gtk_table_set_row_spacings(GTK_TABLE(table),5);//设定格状容器table中的控件行间隔5
    gtk_table_set_col_spacings(GTK_TABLE(table),5);//设定格状容器table中的控件列间隔5
//把格状容器添加到frame内
    gtk_container_add(GTK_CONTAINER(frame),table);
//gtk_table_attach,10个参数:格状容器,放入的控件,下面为table内的坐标比如1,3,1,3,就是横向1至3,和列向1至3
//后面四个为属性和间隔
//7,8参数为GtkAttachOptions,可取三个值:GTK_FILL可填充,GTK_EXPAND可扩展,GTK_SHRINK可缩放
//当然也可以使用gtk_table_attach_defaults函数只有4个参数,没有后面四个(属性和间隔)
    button = gtk_button_new_with_label("0,1,0,1");
    gtk_table_attach(GTK_TABLE(table),button,0,1,0,1,GTK_FILL,GTK_FILL,0,0);//0-1,0-1就是第一个格子

    button = gtk_button_new_with_label("1,3,1,3");
    gtk_table_attach(GTK_TABLE(table),button,1,3,1,3,GTK_FILL,GTK_FILL,0,0);//实际上是占了横向的第2和3的格子,纵向第2和3的格子

    button = gtk_button_new_with_label("0,1,1,3");
    gtk_table_attach(GTK_TABLE(table),button,0,1,1,3,GTK_FILL,GTK_FILL,0,0);//0-1,1-3

    button = gtk_button_new_with_label("1,3,0,1");
    gtk_table_attach_defaults(GTK_TABLE(table),button,1,3,0,1);//1-3,0-1

    button = gtk_button_new_with_label("0,4,3,4");
    gtk_table_attach_defaults(GTK_TABLE(table),button,0,4,3,4);//0-4,3-4

    button = gtk_button_new_with_label("3,4,0,3");
    gtk_table_attach_defaults(GTK_TABLE(table),button,3,4,0,3);//3-4,0-3
    gtk_widget_show_all(window);
    /***************************************************
        gtk_widget_show(window)
    for(i=0;i<4;i++)
       for(j=0;j<4;j++)
       {
          button = gtk_button_new();
          gtk_table_attach_defaults(GTK_TABLE(table),button,i,i+1,j,j+1);
          gtk_widget_show(button);
       }
   ********************************************************/
    gtk_main();
    return FALSE;
}//其Makefile文件为:

CC = gcc
all:
    $(CC) table.c -o table `pkg-config gtk+-2.0 --cflags --libs`

运行后的结果为:
这里写图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值