GTK+是一个软件开发工具包,其设计目的是支持在 X Window系统下开发图形界面的应用程序。GNU所认定的标准桌面环境GNOME就是用GTK+开发的。
GTK+最初是由美国加利福尼亚大学伯克利分校的两名学生Spencer Kimball和Peter Mattis开发而成的。GTK+的全称为:GIMP Toolkit。其最初是开发GIMP而得名,也是为了开发GIMP而研制的一套图形界面库。它为应用软件提供了一套平台无关的,简单易用的图形界面接口,几乎所有的基本图形界面元素,比如窗口,容器,标签,按钮,编辑框,列表框等。
GTK+是建立于GDK基础上的构件库。GDK是GTK+的底层图形库,GDK封装了与平台相关的函数和系统调用,为GTK+提供了一套与平台无关的开发接口。
GTK+库和GDK库均构建于GNU的重要函数库glib之上。glib库是Linux平台下最常用的C语言库,它具有很好的可移植性和使用性。glib库包含了一些标准应用的新扩展来提高GTK+的兼容性。glib为许多标准的,常用的C语言结构提供了相应的替代物。
在Ubuntu Linux下安装GTK+开发包:
sudo apt-get install libgtk-3-dev
安装DevHelp的参考手册:
sudo apt-get install DevHelp
glib库是GTK+和GDK所依赖的基础函数库。glib库的编码风格是半面向对象的,即以面向对象的思想设计,以面向过程的语言(C语言)实线。glib库为许多标准的,常用的C语言结构提供了相应的替代物,glib库的标识符使用一个前缀“g”这是一种通行的命名约定。
glib有一套自己的类型系统,与C语言标准类型的对比如下。
C类型 | GLIB类型 |
---|---|
char | gchar |
short | gshort |
long | glong |
int | gint |
int | gboolean |
float | gfloat |
double | gdouble |
unsigned char | guchar |
unsigned short | gushort |
unsigned long | gulong |
unsigned int | guint |
void * | gpointer |
const void * | gconstpointer |
glib还提供了一些宏的定义。这些宏可分为两类,一类是常用宏,另一类是调式宏。
- 常用宏
宏名 | 说明 |
---|---|
TRUE | gboolean类型,逻辑真 |
FALSE | gboolean类型,逻辑假 |
NULL | 一般用于表示空指针,值为0 |
MAX(a,b) | 返回两者中的较大值 |
MIN(a,b) | 返回两者中的较小值 |
ABS(x) | 返回绝对值 |
CLAMP(x, low, high) | 返回[low, high]范围内的值,x在范围内返回x,比low小返回low,比high大返回high |
GINT_TO_POINTER(p) | 整数转指针 |
GPOINTER_TO_INT(p) | 指针转整数 |
GUINT_TO_POINTER(p) | 无符号整数转指针 |
GPOINTER_TO_UINT(p) | 指针转无符号整数 |
- 调式宏
为什么有调式宏的存在?
使用调式宏能够快速发现程序中的错误。而且可以通过定义编译开关宏G_DISABLE_CHECKS或G_DISABLE_ASSERT来关闭这些宏的功能,所以在软件代码中使用它们不会有性能损失。调式宏还分两种,分别是前提条件检查宏和断言。
既然有两种不同的调式宏,那么它们有特殊的使用规范吗?有的。一般使用前提条件检查来保证传递到程序模块的公用接口的值的合法性,用断言来检查函数或库内部的一致性。这便是调式宏的使用规范。
- (1)前提条件检查宏
#include
g_return_if_fail(condition);
g_return_value_if_fail(condition, retval);
前提条件检查宏的作用?在指定的条件不成立时输出一个警告信息,并立即从当前的函数返回。
这两个宏的区别?g_return_value_if_fail在条件不成立时将第二个参数作为返回值返回,而g_return_if_fail以void返回。
下面是一个小实例:
void getPoint(gint index)
{
g_return_if_fail(index >= 0);
return ;
}
int main()
{
getPoint(-1);
return 0;
}
这段下程序是运行通不过的,在我的机器上它的运行结果如下所示:
biantiao@lazybone1994-ThinkPad-E430:~/sh/GTK+$ ./g_return_if_fail
** (process:2773): CRITICAL **: getPoint: assertion 'index >= 0' failed
biantiao@lazybone1994-ThinkPad-E430:~/sh/GTK+$
#include
g_assert(condition);
g_assert_not_reached();
断言宏的作用?在指定条件不成立时输出一个警告信息,并终止程序的运行。
g_assert()基本上和assert()一样,但是g_assert对G_DISABLE_ASSERT响应。
一个使用g_assert的简单实例:
#include
int main()
{
gint a;
gint *pointer = &a;
g_assert(pointer == NULL);
return 0;
}
说明:这个程序是无法运行的,因为pointer的值不为NULL。它在我的机器上的运行结果如下:
biantiao@lazybone1994-ThinkPad-E430:~/sh/GTK+$ ./g_assert
**
ERROR:g_assert.c:8:main: assertion failed: (pointer == NULL)
已放弃
biantiao@lazybone1994-ThinkPad-E430:~/sh/GTK+$
程序如果执行到g_assert_not_reached()语句,它会调用abort()退出程序并且(如果环境支持)转储一个可用于调式的core文件。g_assert_not_reached()用于标识“不可能”的情况,通常用于检测枚举值的switch语句。下面是一个简单的实例。
#include
#include
enum COLOR {RED, GREEN, BLUE};
int main()
{
enum COLOR clr = 4;
switch(clr)
{
case RED:
printf("red.\n");
break;
case GREEN:
printf("green.\n");
break;
case BLUE:
printf("blue.\n");
break;
default:
g_assert_not_reached();
break;
}
return 0;
}
同样,这个程序也是无法正确运行的。原因在于clr的值为4,不在枚举值的范围(0~2)中,所以程序将执行到default分支,从而调用了g_assert_not_reached宏。它在我的机器上的运行结果如下:
biantiao@lazybone1994-ThinkPad-E430:~/sh/GTK+$ ./g_assert_not_reached
**
ERROR:g_assert_not_reached.c:25:main: code should not be reached
已放弃
biantiao@lazybone1994-ThinkPad-E430:~/sh/GTK+$
最后再来说说glib库的情况。
关于程序的编译。因为glib库的头文件和库文件均不在标准目录下,编译时应当使用反引号将“pkg-config –cflags –libs glib-2.0”命令的执行结果替换到编译命令行中。如下所示:
biantiao@lazybone1994-ThinkPad-E430:~/sh/GTK+$ gcc -o g_assert g_assert.c `pkg-config --cflags --libs glib-2.0`
biantiao@lazybone1994-ThinkPad-E430:~/sh/GTK+$
除了上述的类型和宏之外,glib库中定义了大量的常用函数。其中,g_printf()函数用于向终端输出一条消息,其语法与printf类似。
除了上述内容外,glib库中还定义了单向链表(GSList),双向链表(SList),树(GTree)和哈希表(GHashTable)等数据结构。