二、GTK 信号

 
   信号?有编程经验的应该不陌生,我更愿意把它理解为类似Windows编程中常用到的消息;为什么拿windows作比喻?很简单,因为我从windows编程过来的,这样有助于理解。
    在学习信号前我们先在窗口上增加一个按钮,新增按钮代码如下:

GtkWidget *button;    // 存储按钮对象

button = gtk_button_new_with_label("Hello World");  // 创建按钮对象

gtk_container_add(GTK_CONTAINER(window), button);  // 把按钮添加到窗口上

gtk_widget_show(button);  // 显示按钮

现在增一个函数,即信号处理函数:

void hello(GtkWidget *widget, gpointer data)

{

    g_print("Hello World"n");

}

我们这里的处理函数就这么定义,当然信号处理函数还有其他形式的定义,在后面遇到时再学习;

然后调用g_signal_connect函数把信号与信号处理函数关联起来,如下:

g_signal_connect(G_OBJECT(button), "clicked",

 G_CALLBACK(hello), NULL);       // 把按钮的单击事件与函数hello关联起来

第一个参数button,即发生事件的对象
第二个参数"clicked",信号类型,这里是单击事件,当然还有其他事件可以关联

第三个参数hello就是我们定义的信号处理函数,后面详细介绍

第四个参数为一个指针,见后面介绍:

现在我们回头看看hello函数,它有两个参数,第一个不难看出来,应该是发生事件的对象(也是我的猜测,不过应该89不离10);

第二个参数是个指针,其内容与g_signal_connect的第四个完全相同,就是我们自己传过去的,

我觉得这个参数在将来的学习和工作中会起到很到的作用,呵呵,只是自己的感觉。

这样,我们前面的代码变成现在这个样子了,如下:
#include <gtk/gtk.h>

void hello(GtkWidget *widget, gpointer data)
{
    g_print(
"Hello World"n");
}

int main(int argc, char *argv[])
{
   GtkWidget 
*window;   // GtkWidget可以存储各类gtk对象,这里存储的是窗口对象



   window 
= gtk_window_new(GTK_WINDOW_TOPLEVEL);  // 创建窗口对象   GtkWidget *button;   // 按钮对象

   button 
= gtk_button_new_with_label("Hello World");  // 创建按钮对象

   gtk_container_set_border_width(GTK_CONTAINER(window), 
10);  // 这里是设置窗口的边框宽度

   gtk_init(
&argc, &argv);  // 初始化用参数gtk,这里是必须的

   g_signal_connect(G_OBJECT(button), 
"clicked",

                     G_CALLBACK(hello), NULL);     
// 绑定单击事件

   gtk_container_add(GTK_CONTAINER(window), button);   
// 把按钮添加到窗口上

   gtk_widget_show(button);  
// 显示按钮对象

   gtk_widget_show(window);  
// 显示窗口对象   

   gtk_main ();   
// 运行gtk主程序,简单的理解就是类似window中的消息循环吧,只是浅显的认识   

   
return 0;

}


看到了吧?这就是我的gtk<hello world>程序,点击窗口上面的关闭按钮,呵呵窗口关闭了,咦?程序没有退出?怎么回事?呵呵,因为我们没有处理程序退出的操作,加上现面的代码就OK了。
定义程序退出函数:
void destroy(GtkWidget *widget, gpointer data)
{
    gtk_main_quit ();
}
在创建窗口对象后加入信号与函数关联,代码如下:
g_signal_connect (G_OBJECT (window), "destroy",
              G_CALLBACK (destroy), NULL);
OK,都搞定了,记住,在以后的代码中,我们都需要加入上面这样的代码来退出系统!


补充:一个对象的同一事件可以绑定多个处理函数,函数执行顺序与绑定顺序相同。
posted on 2008-08-11 08:53  dotjava  阅读(719)  评论(0编辑  收藏  举报