关于GTK各个循环函数的介绍与使用
Gtk+主循环的首要目的就是在连接到X服务器的文件描述符上监听事件,并将事件转发到构件上。本节解释怎样使用主循环,怎样给主循环添加新功能:当主循环在指定的时间间隔内空闲时、当一个文件描述符已经读或写就绪、以及当主循环退出时调用一个函数。
2.10.1主循环基本知识
从根本上来说,主循环是由glib实现的。Gtk+将glib主循环连接到Gdk的X服务器,并提供一个方便的接口(glib循环是比Gtk+的循环更低层的)。
gtk_main()函数运行主循环。直到调用gtk_main_quit()函数,gtk_main()才会退出。gtk_main()函数可以 递归调用,每次调用一个gtk_main_quit()就退出gtk_main()函数的一个实例。gtk_main_level()函数返回递归的层 次,也就是:如果没有gtk_main()运行,返回0;如果一个gtk_main()函数在运行,返回1,等等。
gtk_main()函数的所有实例功能都是一样的,它们都监视同一个与X服务器的连接,都对同样的事件队列起作用。gtk_main()实例用于阻塞、遮断一个函数的控制流直到满足某些条件。
所有的Gtk+程序都用这个技巧使应用程序正在运行时main()函数不能退出去。gnome_dialog_run()函数使用了一个递归的主循环,此循环直到用户点击对话框的按钮时它才会返回。
有时候想处理一些事件,又不想将控制交给gtk_main(),可以调用gtk_main_iteration()函数对主循环进行迭代。例如,这 样可以处理单独的一个事件,它依赖于想将什么任务挂起。可以检查是否有任何事件需要通过调用gtk_events_pending()函数处理。同样地, 这两个函数允许临时将控制交还给Gtk+。例如,在一个很长的计算中,想显示一个进度条,必须允许Gtk+主循环周期性地返回,让Gtk+能重画进度条。 可以使用下面的代码:
while(gtk_events_pending())
gtk_main_iteration();
下面是有关主循环的函数:
#include<gtk/gtkmain.h>
voidgtk_main()
voidgtk_main_quit()
voidgtk_main_iteration()
gintgtk_events_pending()
guintgtk_main_level()
2.10.2退出函数
退出函数就是当调用gtk_main_quit()函数时要调用的回调函数。换句话说,回调函数只在 gtk_main()返回之前运行。回调函数应该是一个像下面这样定义的GtkFunction:
typedefgint(*GtkFunction)(gpointerdata);
退出函数是用gtk_quit_add()添加进去的。添加退出函数时,必须指定一个由gtk_main_level()返回的主循环的级别。第二 个和第三个参数指定一个回调函数和回调数据。回调函数的返回值说明了回调函数是否应该再次调用。只要回调函数返回TRUE,它会被重复调用。只要它返回 FALSE,将取消与主循环的连接,并且不会再次调用。所有的退出函数都返回FALSE时,gtk_main()会返回。
gtk_quit_add()函数返回一个ID号码,可以用于用gtk_quit_remove()函数删除该退出函数。还可以通过将回调数据传递给gtk_quit_remove_by_data()函数来删除退出函数。函数列表:退出函数
#include<gtk/gtkmain.h>
guintgtk_quit_add(guintmain_level,
GtkFunctionfunction,
gpointerdata)
voidgtk_quit_remove(guintquit_handler_id)
voidgtk_quit_remove_by_data(gpointerdata)
2.10.3Timeout函数
有时候可能想应该在gtk_main主循环中怎样让GTK做点什么。这时可以创建一个定时(Timeout)函数,隔一定时间(毫秒)就调用一次。Timeout类似于其他编程环境中的定时器控件。下面的函数用于添加一
Timeout函数。
#include<gtk/gtkmain.h>
gintgtk_timeout_add(guint32interval,
GtkFunctionfunction,
gpointerdata);
第一个参数调用定时函数的时间间隔,以毫秒计。第二个参数是要调用的函数,第三个是要传递给函数的参数。函数返回一个整数值“标志”。可以用下面的函数停止调用定时函数:
#include<gtk/gtkmain.h>
voidgtk_timeout_remove(ginttag);
其中tag参数是前一个函数返回的“标志”值。还可以让回调函数返回FALSE或0来停止调用定时函数。也就是说,要想让函数继续调用,必须让它返回一个非0值或TRUE。定期调用的回调函数声明应该是下面的形式:
ginttimeout_callback(gpointerdata);
可以看到,Timeout函数类似于许多可视化编程工具中的Timer控件(计时器)。
2.10.4idle函数
当Gtk+主循环没有其他事情做时,idle函数连续运行。只有在事件队列是空的,并且主循环正常空闲着,正等待着有什么事情发生时,idle函数 才会运行。只要它们返回TRUE,这个函数就会一次又一次地调用;当它们返回FALSE时,函数会被删除,就像调用了gtk_idle_remove() 函数一样。
列在下面函数列表中的idle函数API,与timeout以及退出函数API是一样的。不过,不能在idle函数中调用 gtk_idle_remove()函数,因为它会破坏Gtk+的函数列表。要返回FALSE来删除idle函数。idle函数在对“只此一次”的代码排 队时通常是很有用的,这样的代码一般在所有的事件已经处理之后才运行。相对昂贵(耗费系统资源较多)的操作,比如Gtk+的大小协商以及 GnomeCanvas重绘一般在返回FALSE的idle函数中发生。这保证了代价昂贵的操作只会执行一次,即使多个连续的事件独立地要求重新执行。
Gtk+的主循环包含一个简单的调度程序。idle函数有一个分配给它们的优先级,就像UNIX进程所做的一样,也可以分配一个非缺省的优先级给idle函数。
函数列表:idle函数
#include<gtk/gtkmain.h>
guintgtk_idle_add(GtkFunctionfunction,
gpointerdata)
voidgtk_idle_remove(guintidle_handler_id)
voidgtk_idle_remove_by_data(gpointerdata)
2.10.5输入函数
输入函数用于检查文件描述符的数据(由open(2)或socket(2)返回的文件描述符)。输入函数是在Gdk级处理的。当给定的文件描述符已 经读写就绪时,会调用输入函数。它们对网络应用程序特别有用。关于文件描述符请参考Unix编程方面的参考书。要添加一个输入函数,需要指定要监视的文件 描述符、要等待的状态(读或写就绪),以及一个回调函数/数据对。下面的函数列表列出了这些API。该函数可以用gdk_input_add()返回
的标识符删除。不像quit、timeout和idle函数,从输入函数里面调用gdk_input_remove()函数删除该函数是安全的,Gtk+不会处于输入函数列表的迭代状态。
要指定等待的条件,使用GdkInputCondition标志:
GDK_INPUT_READ
GDK_INPUT_WRITE
GDK_INPUT_EXCEPTION
可以用OR将一个以上的标志连在一起。这些标志对应于传到select()系统调用的三种文件描述符集。要了解详细的内容,请参考UNIX的编程参考书。如果所有条件都得到满足,就会调用输入函数。
回调函数应该是这个样子:
typedefvoid(*GdkInputFunction)(gpointerdata,
gintsource_fd,
GdkInputConditioncondition);
它接受回调数据、被监视的文件描述符以及要满足的条件(可能是一个正在监视的条件的子集)。函数列表:输入函数
#include<gdk/gdk.h>
gintgdk_input_add(gintsource_fd,
GdkInputConditioncondition,
GdkInputFunctionfunction,
gpointerdata)
voidgdk_input_remove(ginttag)
2.11编译应用程序
用前面所介绍的基本概念,已经可以编译全功能的Gtk+/Gnome应用程序了。但是还有一个大问题:如何配置编译选项?一些实用工具如automake、autoconf、libtool等,可以用来简化这一过程。
为了方便维护,同时,也是为了便于使用这些实用工具,应该在编写代码时遵从一些约定。如果要将程序发布为自由软件,最好能使程序源代码的目录结构遵 从 “GNU项目编码标准”。即使应用程序是私有的商用程序,不想公开源代码,从技术上来说,这么做也是一个非常好的选择,因为这些标准都是经过实践检验,能 够让你节省大量的时间和精力。另外还应该在程序代码中包含INSTALL、README的文件。
相关推荐
8. **主循环**:运行`gtk_main()`函数进入GTK事件循环,等待用户事件。 通过这个练习,开发者不仅可以熟悉GTK的基本组件和布局,还能学习如何处理用户输入和响应事件。此外,理解并实践C语言与GTK的结合,有助于...
例如,你可以看到如何使用`gtk_widget_show_all()`显示所有子控件,`gtk_main()`启动主事件循环,`gtk_signal_connect()`连接信号处理函数,以及`gtk_container_add()`将控件添加到容器中。 通过深入研究这些源代码...
**GTK+DFB实验手册v0.9.pdf** 是一份详细介绍了如何使用GTK(GIMP Toolkit)和Direct Frame Buffer (DFB)进行应用开发的实践指南。该手册不仅适用于初学者学习GTK+和DFB的基础知识,同时也为有经验的开发者提供了...
在GTK中,使用`gtk_window_new()`函数创建一个新的窗口。 2. GTK按钮(Button):用于用户交互,如数字按键、运算符按键等。GTK提供`gtk_button_new_with_label()`来创建带有标签的按钮,或`gtk_button_new_from_...
- **Hello World**:教程首先通过一个简单的“Hello World”程序介绍了如何使用GTK+来编写基本的应用程序。这个例子演示了GTK+的基本结构,包括如何初始化库、创建窗口以及响应事件。 #### 二、信号与回调函数 - *...
在核心参考部分中,重点介绍了GTK+的主循环,这是事件驱动程序的基础,负责初始化库、运行主事件循环以及处理事件。加速器组和加速器映射则允许为整个窗口或特定控件设置快捷键,提升应用程序的用户交互体验。 剪贴...
2. **GTK初始化**:学习如何使用`gtk_init()`函数启动GTK运行环境。 3. **创建窗口**:通过`gtk_window_new()`创建一个新的窗口,并设置其标题和大小。 4. **添加布局**:利用`gtk_grid_new()`创建Grid布局,并将其...
使用`gtk_window_new()`函数可以创建一个新的窗口,并通过`gtk_window_set_title()`设置窗口的标题,这里应设为"GTK简单版计算器"。 为了在窗口内添加控件,比如按钮和文本框,我们需要使用`gtk_button_new_with_...
这部分内容讲解了如何使用GTK+的事件循环模型来进行事件处理,并介绍了一些常用的事件类型和处理方法。 - **构建GUI应用程序**:这部分内容着重介绍了如何构建一个完整的GUI应用程序。包括如何组织源代码文件、如何...
《GTK+开发基础》是Linux系统中经典的GTK+编程学习资料,它涵盖了GTK+库的各个方面,为开发者提供了深入理解并熟练使用GTK+进行图形用户界面(GUI)开发的全面指导。GTK+是一个广泛用于创建美观且功能丰富的跨平台...
这段代码展示了上述构建菜单栏的各个步骤,从初始化GTK+库,创建窗口和菜单,到添加菜单项以及设置信号处理器,最终显示窗口并启动事件循环。 #### 五、总结 通过以上分析,我们可以看到GTK+为构建复杂的图形用户...
这通常包括`#include <gtk/gtk.h>`来引入所需的GTK+头文件,然后初始化GTK+环境,创建窗口对象,设置窗口的属性如大小、标题等,最后调用`gtk_main()`函数启动事件循环。 接着,游戏界面的构建需要使用GTK+的容器...
6. **运行主循环**:最后,调用`gtk_main()`启动事件处理循环。 #### 五、高级特性与技巧 1. **布局管理**:Gtk+提供了多种布局管理器,如`GtkBox`、`GtkGrid`和`GtkStack`等,可以帮助开发者更高效地组织控件布局...
**WebKitGTK+、Gtk+、GObject、GLib与GDK API合集详解** WebKitGTK+是WebKit渲染引擎的一个版本,它为GTK+应用程序提供了Web内容的显示和交互能力。这个合集着重于WebKitGTK+及其相关的GTK+、GObject、GLib和GDK ...
例如,"entry.c"可能包含了与用户输入交互的部分,"pageX.h"可能是各个视图或窗口的定义,而"generaldef.h"和"creatwindow.h"可能包含了通用定义和窗口创建的函数。 在Linux环境中,开发者需要利用GTK提供的API来...
glibc是Linux操作系统的关键组成部分,它负责与硬件交互,并且提供了大量的函数来支持应用程序的开发。 ##### 1.2 glibc和glib - **glib**: 是一个跨平台的C语言函数库,主要用于GTK+库和GNOME桌面环境。glib并不是...
这部分代码说明了gtk_init()函数用于初始化GTK库,gtk_window_new()用于创建一个窗口,gtk_widget_show()用于显示窗口,以及gtk_main()用于启动GTK的主循环。 代码段: ```c #include <gtk/gtk.h> int main(int ...
此章将教授Bash shell的基本语法,如变量、条件语句、循环结构以及函数的使用,同时还会涉及shell脚本的调试和优化技巧。 第11章 gcc的使用与开发:gcc是GNU Compiler Collection的简称,是Linux下最常用的C/C++...
3. **函数编程**:科学计算器的各个功能,如加、减、乘、除,以及更复杂的科学运算,会被封装成独立的函数。这些函数接受必要的参数,执行计算,并返回结果。 4. **内存管理**:C语言提供了手动内存管理,包括动态...