王朝网络
分享
 
 
 

Linux GUI编程笔记之GTK+篇(1)

王朝system·作者佚名  2006-01-09
宽屏版  字体: |||超大  

Linux GUI编程笔记之GTK+篇(1)

----信号-回调函数和事件

GTK+(GIMP Toolkit)是一个在Linux平台上比较流行的GUI构建工具,著名的Gnome平台就是基于它的。虽然它是用C语言编写的,但是它却成功的应用了面向对象和回调函数这些技术。在它的主页www.gtk.org上有一个详细的教程下载(国内有网友也做了翻译),所以我在这里也不详细的介绍它的内容了。作为自己学习GTK+编程的笔记(我现在在看英文的GTK文档),我只是着重分析一些在GTK教程上比较难懂的,然后比较关键的知识点。有什么错误纰漏的地方,请各位网友指正。

首先,让我们来看一个简单的例子,然后引出我们今天的讨论的主题:

#include <gtk/gtk.h>

/* This is a callback function */

void hello( GtkWidget *widget,

gpointer data )

{

g_print ("Hello World\n");

}

int main( int argc,

char *argv[] )

{

GtkWidget *window;

GtkWidget *button;

/* init the program */

gtk_init (&argc, &argv);

/* make a new button */

window = gtk_window_new (GTK_WINDOW_TOPLEVEL);

g_signal_connect (G_OBJECT (window), "destroy",

G_CALLBACK (gtk_main_quit), NULL);

gtk_container_set_border_width (GTK_CONTAINER (window), 10);

/* make a new button */

button = gtk_button_new_with_label ("Hello World");

g_signal_connect (G_OBJECT (button), "clicked",

G_CALLBACK (hello), NULL);

/* add the button to the window */

gtk_container_add (GTK_CONTAINER (window), button);

/* show the widgets */

gtk_widget_show (button);

gtk_widget_show (window);

gtk_main ();

return 0;

}

假设文件保存为: hello.c

然后编译: gcc -o hello hello.c `pkg-config --cflags --libs gtk+-2.0`

(关于这个奇怪的gcc编译选项,GTK+文档上有详细解释)

用: ./hello 运行就出现一个带有一个按钮的小窗口,如下图:

每个GTK+程序的框架都是差不多的。像我们这个程序,在main()函数中用gtk_init(&argc, &argv)初始化环境,然后定义一些控件让他们显示,最后用gtk_main()进入主循环,等待各种事件的发生(了解Windows程序设计的朋友会感觉这和Windows GUI编程模式差不多:)。这里最重要的地方就是把各种事件通过回调函数(callback function)和控件联系起来,使控件在某事件发生时(比如鼠标点击)产生某种响应。

什么是“回调函数”呢?在上面的程序中,void hello()函数就是一个回调函数。通过g_signal_connect()这个信号连接函数使之与button连接,在button被点击(clicked)时就触发hello()函数的运行(各种不同的GUI构建工具其基本原理都是这样的)。下面让我们来看看这个奇妙的信号连接函数是如何工作的:

这是第一种信号连接函数的原型声明:

gulong g_signal_connect( gpointer *object, //发出信号的控件

const gchar *name, //信号名称

GCallback func, //回调函数(对信号要采取的动作)

gpointer data ); //传给回调函数的数据

它对应的回调函数是:

void func( GtkWidget *widget, //发出信号的控件

gpointer callback_data ); //穿过来的数据

表示object这个控件在接收到name信号以后调用func函数。比如上面的例子:

g_signal_connect (G_OBJECT (button), "clicked",

G_CALLBACK (hello), NULL);

就是指button这个控件在接收鼠标点击这个动作时,就发出”clicked"这个事件,我们捕获这个事件后调用hello()这个回调函数。然后hello()函数里面第一个参数widget现在就是button,第二个参数data为NULL(从g_signal_connect()传过来的)。值得注意的是在GTK+中信号是用字符串形式表示的(比如这里的“clicked”)。

现在我们应该了解了GTK+程序的工作原理了,再复杂的Gnome程序其基本原理就是上面我们分析的信号捕捉=>函数回调 。还有一种信号连接函数是这样的:

gulong g_signal_connect_swapped( gpointer *object, //发出信号的控件

const gchar *name, //信号名称

GCallback func, //回调函数

gpointer *widget ); //传给回调函数的数据

它和g_signal_connect()作用相同,不同的只是它的回调函数只接收一个参数,它对应的回调函数是:

void callback_func( GtkObject *object );

这对于调用GTK+自带的一些只接收一个参数的函数(比如gtk_widget_destroy)来说是十分必要的,比如我们想让鼠标点击按钮时让窗口关闭,就可以加这样一个信号连接函数:

g_signal_connect_swapped (G_OBJECT (button), "clicked", //让鼠标发出"clicked"事件

G_CALLBACK (gtk_widget_destroy), //调用系统函数使窗口关闭

G_OBJECT (window)); //把window作为参数传给gtk_widget_destroy()

信号连接函数不仅可以和控件产生的信号进行连接,而且可以和特殊的X-windows”事件“进行连接。我们知道,Gnome/KDE之类的窗口管理程序自己可以产生一些事件(比如按Alt+F4会产生一个窗口关闭事件)。所以GTK也允许我们用g_signal_connect()使我们的程序对窗口管理器产生的事件作出正确的反应。下面是一些常见的X-windows事件:

button_press_event

button_release_event

scroll_event

delete_event

这些事件的意思一目了然,就像GTK各函数的意思一样(比如gtk_main_quit肯定是退出程序了:)

只是对事件作出反应的回调函数和前面的有点不同:

static gint callback_func( GtkWidget *widget, //接收事件的控件

GdkEvent *event, //事件名称

gpointer callback_data ); //传给回调函数的数据

这个函数的返回值为TRUE或FALSE,返回TRUE的时候表示GTK程序已经完成事件处理,窗口管理器不用再触发下面的事件,返回FALSE时继续调用后续函数。再GTK文档上有一个窗口管理器发出delete_event事件的例子,当callback函数返回TRUE时程序不再调用destroy事件,而返回FALSE时程序继续调用destroy事件使得程序退出。

好的,我们关于信号和事件处理部分已经讲玩了。但是我们只是一个劲地往程序里加事件,有没有方法使得我们能够去掉连在控件上的信号,事件呢?答案是肯定的。

注意g_signal_connect()函数的返回值gulong,还有许多比如gint, gchar等,这是GTK+对ANSI C数据类型的包装,使得GTK的移植性更好。这里gulong表示g_signal_connect()返回了一个信号ID,用来代表这个事件信号。我们可以利用这个ID来去掉控件上这个事件,这是去掉信号连接的函数原型:

void g_signal_handler_disconnect( gpointer object, //信号和哪个控件有一腿:)

gulong id ); //信号的ID

在GTK+的API里面还有一些事件,信号方面的函数,比如:

/* 暂停信号处理 */

void g_signal_handler_block( gpointer object,

gulong id );

/* 重新进行信号处理 */

void g_signal_handler_unblock( gpointer object,

gulong id );

如果你对这个有兴趣研究,可以参阅GTK的API文档,里面有简介明了的介绍。

OK! 终于完成了我们Linux GUI编程的第一课了:) 下一次让我们来学习一下如果在GTK窗口上摆放控件。

--------2004-7-28

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
>>返回首页<<
推荐阅读
 
 
频道精选
 
静静地坐在废墟上,四周的荒凉一望无际,忽然觉得,凄凉也很美
© 2005- 王朝网络 版权所有