第16章 GDK基础Word文件下载.docx
- 文档编号:21809102
- 上传时间:2023-02-01
- 格式:DOCX
- 页数:47
- 大小:403.73KB
第16章 GDK基础Word文件下载.docx
《第16章 GDK基础Word文件下载.docx》由会员分享,可在线阅读,更多相关《第16章 GDK基础Word文件下载.docx(47页珍藏版)》请在冰豆网上搜索。
本章介绍了关于GDK的一些基本知识,这些也是创建构件和绘图的基础。
更多的GDK细节内容,请参考gdk.h头文件。
如果想了解Gdk函数的实现细节(比如它对应于Xlib的哪一个函数),可以看一下Gdk的源代码以确定它所封装的Xlib函数,然后用man指令参看该函数的手册页。
例如,下面是gdk_draw_point()函数的实现代码:
void
gdk_draw_point(GdkDrawable*drawable,
GdkGC*gc,
gintx,
ginty)
{
GdkWindowPrivate*drawable_private;
GdkGCPrivate*gc_private;
g_return_if_fail(drawable!
=NULL);
g_return_if_fail(gc!
drawable_private=(GdkWindowPrivate*)drawable;
if(drawable_private->
destroyed)
return;
gc_private=(GdkGCPrivate*)gc;
XDrawPoint(drawable_private->
xdisplay,drawable_private->
xwindow,
gc_private->
xgc,x,y);
}
每一个数据结构都被转换给它的一个“私有”版本,该“私有”版本包含了与GDK正在使用的特定窗口系统的相关信息,这样可以将与特定窗口系统相关的函数声明排除在gdk/gdk.h头文件外。
每个数据结构的“私有”版本都包含一个封装的Xlib数据结构,且这个数据结构被传递到XDrawPoint()函数中,所以XDrawPoint()函数的文档也适用于gdk_draw_point()函数。
16.2GdkWindow
GdkWindow是Xlib窗口对象的封装。
一个GdkWindow代表屏幕上的一个区域,可以显示或隐藏起来(在Xlib里面称为映射或反映射窗口),也可以捕获GdkWindow接收到的事件,还可以在里面绘制图像,移动或调整图像的尺寸。
GdkWindow是以树状结构组织的,也就是说,每一个窗口都可以有子窗口。
子窗口是相对于父窗口的位置定位的,当父窗口移动时,子窗口也会移动。
子窗口不会在父窗口边界外的区域绘出(也就是说,它们会被父窗口剪裁)。
所谓GdkWindow窗口的树状组织并不是针对每个应用程序的,实际上有一个由X服务器和窗口管理器控制的窗口的全局树。
根窗口没有父窗口,所有窗口都是从它派生而来的。
作为桌面背景,根窗口的全部或部分总是可见的。
每个窗口都可以为不同的Linux进程所拥有,一些窗口是由窗口管理器所创建的,还有一些来自于用户的应用程序。
GdkWindow和GtkWindow是完全不同的东西。
GtkWindow是一个Gtk+构件,用于表示顶级(toplevel)窗口(顶级窗口是在窗口层次中由应用程序控制的最高级别的窗口)。
典型情况下,窗口管理器为顶级窗口创建各种装饰,包括标题条、关闭按钮以及窗口外观等。
要理解X窗口首先要知道它是X服务器上的一个对象,这一点很重要。
X客户对每一个窗口获得一个独一无二的整数ID号,并用ID号码引用该窗口。
这样,所有的窗口操作都发生在服务器上,并且所有与X窗口打交道的函数都要通过网络传输。
GdkWindow是由X返回的整数ID号的一个封装。
它确实保存一些信息的本地拷贝(比如说窗口的尺寸),所以一些Gdk操作比相应的Xlib操作效率更高。
还有,GdkWindow本质上是服务器端对象的一个句柄。
许多Gdk对象都是相似的,字体、像素映射图片、鼠标光标等等也是服务器端对象的句柄。
16.2.1GdkWindow和GtkWidget
许多GtkWidget子类都有一个相关联的GdkWindow窗口。
理论上,Gtk+应用程序可以只创建一个顶级窗口,并将所有构件画在里面。
然而,这么做并没有什么实际意义,因为GdkWindow允许X窗口系统自动处理许多细节。
例如,Gdk所接收到的事件都使用它们所发生的窗口标志,这使得Gtk+能很快确定每个事件是哪个构件发生的。
有一些构件是没有与之相关联的GdkWindow窗口的,它们称为“无窗口”的构件,用一个GTK_NO_WINDOW标记来标志它们(可以用GTK_WIDGET_NO_WINDOW()宏来测试它们)。
没有窗口的构件会将自身绘制在其父构件容器的GdkWindow窗口上。
无窗口构件相对较小,占用资源较少,一般将它们称为“轻量级”的,GtkLabel构件就是一个最常见的例子。
因为事件总是由GdkWindow窗口接收的,无窗口构件不能接收事件。
如果想让无窗口构件捕获事件,可以使用GtkEventBox容器构件。
16.2.2GdkWindow属性
创建GdkWindow时,gdk_window_new()函数允许指定窗口的所有属性,这些属性以后也可以再改变。
要指定多个属性,可以向函数传递一个GdkWindowAttr对象。
GdkWindowAttr对象的内容就是GdkWindow窗口的属性。
下面是GdkWindowAttr结构的定义:
typedefstruct_GdkWindowAttrGdkWindowAttr;
struct_GdkWindowAttr
gchar*title;
gintevent_mask;
gint16x,y;
gint16width;
gint16height;
GdkWindowClasswclass;
GdkVisual*visual;
GdkColormap*colormap;
GdkWindowTypewindow_type;
GdkCursor*cursor;
gchar*wmclass_name;
gchar*wmclass_class;
gbooleanoverride_redirect;
};
因为GdkWindowAttr结构的一些成员是可选的,所以gdk_window_new()函数用一个attributes_mask参数指定哪一个可选成员里包含有效的数据。
Gdk只检查在屏蔽值里面指定的成员,这样可以让不感兴趣的成员保留缺省值。
下面的函数列表简要概括了这些值。
没有attributes_mask标志的成员必须指定,因为它们没有缺省值。
gdk_window_new()函数最典型的是用在构件的实现中,用来创建构件的GdkWindow。
在其他场合下极少用到它。
gdk_window_destroy()函数销毁GdkWindow窗口。
函数列表:
GdkWindow
#include<
gdk/gdk.h>
GdkWindow*gdk_window_new(GdkWindow*parent,
GdkWindowAttr*attributes,
gintattributes_mask)
voidgdk_window_destroy(GdkWindow*window)
下面简要介绍GdkWindowAttr结构中各个成员的意义。
第一个成员title是GdkWindow的标题,它只对顶级窗口才有实际意义,大多数窗口管理器把它放在标题条上。
通常,不要在创建GdkWindow窗口时指定title值,应该让用户调用gtk_window_set_title()函数来指定它。
第二个成员event_mask是窗口的事件屏蔽,它决定这个窗口接收什么事件。
后面会有详细的介绍。
第三个和第四个成员x、y是窗口的X、Y坐标,它们是以像素度量的;
这两个坐标是相对于父窗口原点的坐标。
每个窗口的原点都是它的左上角(西北角)。
注意,它们是16位的有符号整数。
X窗口最大可以是32768像素,它可以是负数值,不过会被它的父窗口剪裁掉(只有在父窗口内部的区域才是可见的)。
第五个和第六个成员width、height是窗口的宽度和高度,它们是以像素度量的,也是16位的有符号整数。
第七个成员GdkWindowClass可取以下两种值:
•GDK_INPUT_OUTPUT:
GdkWindow是一个普通窗口
•GDK_INPUT_ONLY:
GdkWindow是一个窗口,它有一个位置,能接收事件,但没有视觉上的表示,也就是说它是不可见的。
它的子窗口也必须是这种类型的。
你可以为这种窗口设置光标和其他的属性,但是没有办法把窗口画出来(因为它是不可见的)。
这种窗口有时候用于捕获事件或改变两个普通窗口重叠区域的鼠标光标。
第八个成员visual(视件)描述了一个显示器的颜色处理特征;
第九个成员colormap(颜色表)包含了用于绘画的颜色。
第十个成员window_type指定GdkWindow的类型。
窗口可以是下面几种不同类型之一,由GdkWindowType枚举类型指定:
•GDK_WINDOW_ROOT:
是根窗口的Gdk封装类型,在初始化时创建。
•GDK_WINDOW_TOPLEVEL:
是一个顶级窗口。
在这种情况下,gdk_window_new()函数的parent参数应该设为NULL。
Gdk自动使用根窗口作为它的父窗口。
•GDK_WINDOW_CHILD:
是一个在顶级窗口中的下级窗口。
•GDK_WINDOW_DIALOG:
基本上与顶级窗口是一样的。
它的父窗口应该是NULL,并且Gdk会替换根窗口。
应该设置一个窗口类提示(wmclass_name)告诉窗口管理器这个窗口是一个对话框,一些窗口管理器会考虑这些情况并作适当的处理。
•GDK_WINDOW_TEMP:
用于弹出菜单或其他类似的东西。
它是一个只需暂时存在的窗口。
它是一个顶级窗口,所以它的父窗口应该是NULL。
这种窗口的鼠标光标总是与它们父窗口的一样。
所以它们会忽略属性结构中的相关成员值。
•GDK_WINDOW_PIXMAP:
根本就不是窗口。
在Gdk中GdkPixmap和GdkWindow差不多是同样处理的,所以Gdk用同样的结构表示它们;
它们可以视为GdkDrawable类型。
•GDK_WINDOW_FOREIGN:
标识一个不是由Gdk创建的窗口的封装。
对gdk_window_new()来说,只有GDK_WINDOW_TOPLEVEL、GDK_WINDOW_CHILD、GDK_WINDOW_TEMP和GDK_WINDOW_DIALOG是有效的。
库用户不会创建一个GDK_WINDOW_ROOT。
pixmap(GDK_WINDOW_PIXMAP)是用gdk_pixmap_new()创建的。
外来窗口(GDK_WINDOW_FOREIGN)是在Gdk外部创建并用gdk_window_foreign_new()封装的X窗口。
第十一个成员cursor指定在这个窗口中的鼠标的指针(光标)形状。
第十二个成员wmclass_name前面已经介绍过了。
写构件时,通常不设置类提示,它只与顶级窗口有关。
Gtk+提供了gtk_window_set_wmclass()函数,程序员可以将它设置为具有确切含义的值。
GdkWindowAttr的最后一个成员override_redirect决定窗口是否“替换重定向”的。
通常,窗口管理器截获所有对顶级窗口的显示、隐藏、移动或尺寸调整请求。
你可以重定向或取消这些请求,让顶级窗口按窗口管理器的布局策略行事。
将override_redirect设置为TRUE,禁止窗口管理器对窗口的管理。
因为窗口管理器不能移动设置了这个标志的窗口,通常也不会为这样的窗口设置标题条或其他的装饰。
注意,所有的GDK_WINDOW_TEMP窗口都将这个成员设为TRUE;
GDK_WINDOW_TEMP通常用作弹出菜单,窗口管理器不能控制它。
一般不应该改变override_redirect成员。
如果指定了正确的GdkWindowqType,缺省值差不多总是正确的。
不过还是有一些例外,例如Gnome面板应用程序设置了这个成员。
16.3视件和颜色表
硬件之间总存在差别。
最原始的X服务器只支持两种颜色,每一个像素只能是on或off(开或关)。
这就是“每像素一位”(bpp)显示模式。
每像素一位的显示模式称为深度为1。
多数高级的X服务器支持每像素24或32位,还允许以窗口为基础指定不同的深度。
每像素24位允许224(16777216)种像素,包含了比人眼能分辨的还要多的颜色。
从概念上说,位图显示由一个矩形的像素网格组成。
每个像素由一些固定的位数组成;
像素以一种硬件相关的方法映射为可视的颜色。
考虑这种概念的一种方法就是想象一个二维的整数数组,整数的大小等于要求的位数。
换一种说法,可以想象一种显示就像一个“位平面”栈,或“位”的二维数组。
如果每个平面都平行于其他平面,那么一个像素就是一根在相同坐标处穿过每个平面的垂线,并且从每一个平面处获得一位。
这就是术语“深度”的起源,因为每个像素的位数等于位平面栈的深度。
在X窗口系统中,像素代表在一个颜色查找表中的入口。
一种颜色就是一组红、绿、蓝(RGB)值—监视器以一定比率混合红绿蓝光以显示每个像素。
例如,考虑一种八位的显示模式:
八位不足以为现实中的颜色编码,只可能为很少部分的RGB值编码。
作为替代,数据位被解释为整数,用于为RGB颜色值做索引。
这个颜色表称为colormap(颜色表),有时,你也可以修改它以包含要使用的颜色,虽然这样做是硬件相关的(一些colormap是只读的)。
视件(visual)用来决定像素的位模式如何转换为一个可见的颜色。
因而,视件还定义了颜色表如何工作。
在八位显示中,X服务器也许将每个像素解释为一个包含256种可能颜色值的颜色表的索引。
典型情况下,24位视件有三个颜色表:
一个是红色的浓淡值,一个是绿色的浓淡值,一个是蓝色的浓淡值。
每个颜色表用一个八位的值索引;
三个八位值组成24位的像素。
视件定义了像素内容的含义,还定义了颜色表是只读的还是可修改的。
简而言之,视件就是特定X服务器的颜色容量的描述。
在Xlib中,你得围绕视件做很多罗嗦的事,但是Gdk和Gtk+能极大地简化了这些繁琐工作。
16.3.1GdkVisual
Xlib能报告一个所有可用的视件以及相关信息的列表;
Gdk在一个称为GdkVisual的结构中保持一个这些信息的客户端拷贝。
Gdk能报告可用的视件,并将它们以不同的方式分级。
在多数时候,只需用gdk_visual_get_system()函数就可以了,它返回一个指向缺省视件的指针。
如果正在写一个GtkWidget构件,gtk_widget_get_visual()函数将返回应该使用的视件。
返回的视件不是一个拷贝,所以不需要释放它,Gdk将永久保存视件。
获取缺省视件
GdkVisual*gdk_visual_get_system()
下面是GdkVisual结构的定义,大多数成员都用于由颜色计算像素值。
typedefstruct_GdkVisualGdkVisual;
struct_GdkVisual
GdkVisualTypetype;
gintdepth;
GdkByteOrderbyte_order;
gintcolormap_size;
gintbits_per_rgb;
guint32red_mask;
gintred_shift;
gintred_prec;
guint32green_mask;
gintgreen_shift;
gintgreen_prec;
guint32blue_mask;
gintblue_shift;
gintblue_prec;
16.3.2视件的类型
视件用不同的度量方法加以区分。
它们可以是灰度级或者RGB值,颜色表可以是可修改的或者固定的,像素值可以是单个的颜色表或者包含了压缩的红、绿、蓝的索引值。
下面是GdkVisualType的可能取值:
•GDK_VISUAL_STATIC_GRAY:
意味着显示器是单色的或者灰度的,颜色表不能修改。
一个像素值只是一个灰度级别,每个像素都是“硬编码”,分别代表一个确定的屏幕上的颜色。
•GDK_VISUAL_GRAYSCALE:
意味着显示器是可修改的,但是只有灰度的级别才可能修改。
像素代表在颜色表中的一个入口,所以给定的像素在不同的时候能够代表不同的灰度级别。
•GDK_VISUAL_STATIC_COLOR:
代表一种颜色显示,它使用单个只读的颜色表而不是红、绿、蓝每种颜色各一个单独的颜色表。
这种显示差不多就是12位或更少(使用单个颜色表的24位显示器需要一个带224个入口的颜色表,差不多有500MB)。
这是一种恼人的视件,因为它的可用颜色太少,而且不能改变成它们的实际颜色。
•GDK_VISUAL_PSEUDO_COLOR:
从很多年前开始,就一直是低端PC硬件的常用视件。
如果有一个1MB显存、256色的显示卡,这极有可能就是你的X服务器的视件。
它代表一种具有读/写颜色表的颜色显示。
像素只对单个颜色表索引。
•GDK_VISUAL_TRUE_COLOR:
是带三个只读颜色表的颜色显示,红、绿、蓝每种颜色有一个颜色表。
一个像素包含三个索引,每个颜色表一个。
在像素值和RGB三元组之间有固定的数学关系,可以用下面的公式从[0,255]间的红、绿、蓝值获取像素值:
gulongpixel=(gulong)(red*65536+green*256+blue)。
•GDK_VISUAL_DIRECT_COLOR:
是一种有三个读写颜色表的颜色显示。
如果使用Gdk颜色处理例程,它们只是简单地填充所有三个颜色表以模拟真彩显示。
16.3.3颜色和GdkColormap
GDK使用GdkColor存储RGB值和像素值。
红、绿、蓝值是以16位无符号整数给出的,取值范围为0到65535。
像素的内容依赖于视件。
下面是GdkColor结构定义:
typedefstruct_GdkColorGdkColor;
struct_GdkColor
gulongpixel;
gusho
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 第16章 GDK基础 16 GDK 基础
![提示](https://static.bdocx.com/images/bang_tan.gif)