收藏 分享(赏)

GTK+2.0-----构件定位.doc

上传人:fmgc7290 文档编号:8955632 上传时间:2019-07-18 格式:DOC 页数:14 大小:192.50KB
下载 相关 举报
GTK+2.0-----构件定位.doc_第1页
第1页 / 共14页
GTK+2.0-----构件定位.doc_第2页
第2页 / 共14页
GTK+2.0-----构件定位.doc_第3页
第3页 / 共14页
GTK+2.0-----构件定位.doc_第4页
第4页 / 共14页
GTK+2.0-----构件定位.doc_第5页
第5页 / 共14页
点击查看更多>>
资源描述

1、GTK+2.0-构件定位GTK+2.0 2008-12-13 10:25:20 阅读 263 评论 0 字号:大中小 订阅 构件的显现、映射和显示构件可以按它们是否有 G d k Wi n d o w 窗口分类。有两种 G t k +构件,一种有一个相关联的 G d k Wi n d o w 窗口,另一种没有。大多数构件都有一个相关联的 G d k Wi n d o w 窗口,构件就绘制在这个窗口上。这里的 G d k Wi n d o w 窗口和 G t k +里的 G t k Wi n d o w 窗口是不一样的。G d k Wi n d o w 不是一个用户可见的对象,而是一个 X 服务

2、器用于划分屏幕的抽象概念。一个 G d k Wi n d o w 窗口,对 X 服务器给出了关于将要显示的图形的结构信息。因为 X 窗口系统是网络透明的,有可能 X 窗口的显示位置和 X 服务器不在同一台机器上,这样有助于减少网络流量。G t k Wi n d o w 是一个窗口构件,它是一个用户可见的对象。还有一些构件,比如说 G t k L a b e l 构件,没有与之相关联的 G d k Wi n d o w;它们被称为“无窗口构件” ,并且是相对轻量级的。没有相关联窗口的构件绘制在它的父构件的 G d k Wi n d o w 窗口上。一些操作,例如捕获一个事件,要求有一个 G d

3、k Wi n d o w 窗口,因此不能在无窗口构件上做这些操作。构件要经过一系列与它们的 G d k Wi n d o w 相关的状态:? 如果一个构件相应的 G d k Wi n d o w 被创建出来,称为该构件被显现( r e a l i z e)。用 g t k _ w i d g e t _ r e a l i z e ( )函数显现一个构件,用 g t k _ w i d g e t _ u n r e a l i z e ( )函数反显现(u n r e a l i z e d)构件。因为 X 窗口必须有一个父窗口,如果一个构件已经显现,它的父窗口也必然已显现。? 如果在构件的

4、 G d k Wi n d o w 上调用了 g d k _ w i n d o w _ s h o w ( )函数,称为该构件被映射( m a p)了。这意味着服务器已经要求在屏幕上显示这个构件的 G d k Wi n d o w 窗口。很明显, G d k Wi n d o w 窗口必须存在,就是说,被映射的构件必然已被显现。? 如果当一个构件的父构件被映射时,它也被映射到屏幕上,这个构件就是可见的。这意味着已经对该构件调用了 g t k _ w i d g e t _ s h o w ( )函数。通过调用 g t k _ w i d g e t _ h i d e ( )函数,一个构件可

5、以绘制为不可见的,这或者是取消未决的映射(已经确定了映射的时间,但还未映射),或者反映射该构件(隐藏它的 G d k Wi n d o w 窗) 。因为顶级构件没有父构件,当它们一显示,它们同时就被映射了。在典型的用户代码中,只需调用 g t k _ w i d g e t _ s h o w ( )函数。这暗含当它的父构件一旦被显现和映射,该构件就被显现和映射。要理解的是: g t k _ w i d g e t _ s h o w ( )函数并不会立即生效,这一点很重要,它仅仅是确定构件被显示出来的时间。也就是说,不用担心显示构件的顺序(不必一定要先显示子构件,再显示父构件)。但是,这时还

6、不能立即访问这个构件的G d k Wi n d o w 窗口。有时,又确实需要在映射之前访问构件的 G d k Wi n d o w 窗口;在这样的情况下,要手工调用 g t k _ w i d g e t _ r e a l i z e ( ) 函数来创建这个 G d k Wi n d o w。如果机会适当,g t k _ w i d g e t _ r e a l i z e ( )函数还会显现构件的父构件。使用 g t k _ w i d g e t _ r e a l i z e ( )函数的情况是不多见的,如果感觉到一定要这么做时,也许是使用了不正确的方法。上面介绍了创建构件的过程。

7、销毁构件自动地将以上事件的整个次序倒过来,递归取消子构件和构件本身的显现。正如上面所提到的,对构件调用 g t k _ w i d g e t _ s h o w ( )函数之后,构件并不一定会显示。只有当构件的所有父构件(直到最高级别的父构件)全部显示之后,它才会显示。因而,一般情况下,应该最后对最高级别的构件 G t k Wi n d o w 调用 g t k _ w i d g e t _ s h o w ( )函数。否则,如果先显示高级别的构件,用户可能会看到窗口先出现在屏幕上,然后子构件一个一个显示在屏幕上。用户或许会觉得你的程序不够专业,甚至不正确。下面是显现、映射和显示构件的相关

8、函数。函数列表: 显示/映射/显现构件#include /* 显现一个构件,创建该构件的 G d k W i n d o w * /void gtk_widget_realize(GtkWidget* widget)/* 反显现构件,销毁该构件的 GdkWindow*/void gtk_widget_unrealize(GtkWidget* widget)/ *映射构件,构件的 G d k W i n d o w 显示在窗口上*/void gtk_widget_map(GtkWidget* widget)/ *反映射构件,隐藏构件的 G d k W i n d o w。注意,构件的 G d k

9、 W i n d o w 还存在*/void gtk_widget_unmap(GtkWidget* widget)/ *显示构件,当构件的父构件(向上递归直到最高级别构件)显示时,*构件将显示在屏幕上,*/void gtk_widget_show(GtkWidget* widget)/ *隐藏构件,构件的 G d k W i n d o w 依然存在*/void gtk_widget_hide(GtkWidget* widget)其他的构件概念本节介绍了几个其他与 G t k Wi d g e t 基类相关的概念,其中包括敏感性、焦点以及构件状态。1. 敏感性构件可以是敏感或不敏感的,不敏感

10、的构件不能对输入进行响应。一般不敏感的构件是灰色的,不能接收键盘焦点。用 g t k _ w i d g e t _ s e t _ s e n s i t i v e ( )函数改变构件的敏感度。函数列表: 改变敏感度#include / *设置构件的敏感性, w i d g e t 参数是要设置的构件, s e t t i n g 设置为 T R U E 时,*构件是敏感的,s e t t i n g 设置是 F A L S E 时,构件不敏感 * /void gtk_widget_set_sensitive(GtkWidget* widget,gboolean setting)构件缺省是

11、敏感的。只有构件的所有容器是敏感的,构件才能是敏感的。也就是,可以通过设置容器的敏感性来让整个容器内的构件敏感( 或不敏感)。构件“真正的” 敏感性,包括它的父构件的状态,可以用 G T K _ W I D G E T _ I S _ S E N S I T I V E ( )宏测试。构件本身的敏感性,只与构件的父构件的敏感性有关,可以用 G T K _ W I D G E T _ S E N S I T I V E ( )宏来查询。宏列表:敏感性#include GTK_WIDGET_IS_SENSITIVE(widget)GTK_WIDGET_SENSITIVE(widget)2. 焦点某

12、个时候,在一个顶级窗口中某个构件可能具有键盘焦点。顶级窗口接收到的任何键盘事件都被发送到这个构件。这一点很重要,因为在键盘上击键应该只有唯一的一种效果,例如,只能更改一个文本输入区域。大多数构件在具有焦点时,会有一个视觉的指示。当使用缺省的 G t k +主题(T h e m e)时,典型情况下,有焦点的构件有一个细黑框环绕着。用户可以用方向键或 Ta b 键在构件之间移动焦点。当用户用鼠标点击构件时,焦点也会移过去。对键盘导航来说,焦点的概念是很重要的。例如,按下回车键或空格键会“激活” 许多具有焦点的构件;可以用 Ta b 键在按钮之间移动,按下空格键激活这个按钮。3. 独占构件能够从其他

13、构件中独占( g r a b)鼠标指针和键盘。所谓独占,就是构件是“ 模态”的,用户只能向这个构件中输入字符,键盘焦点也不能改变到其他构件。独占输入的一个典型理由是:创建一个模态对话框时,如果窗口是独占的,则不能与其他的窗口交互。注意,还有另外一个 G d k 级的“独占”。G d k 键盘和鼠标指针的独占发生在 X 服务器范围内,也就是,其他应用程序不能接收到键盘和鼠标事件。构件独占是一个 G t k +概念,它只独占同一个应用程序中的其他构件的事件。4. 缺省每个窗口至多有一个缺省构件。例如,典型情况下,对话框都有一个缺省按钮,当用户按回车键时,相当于点击了这个按钮。5. 构件状态构件的状

14、态值决定了它们的外观:? Normal:就是正常该有的样子。? Active:例如,按钮正被按下,或检查按钮(check box)正被选中。? P r e l i g h t:鼠标指针越过一个构件(典型情况,按下会有一些效果) 。例如,当鼠标越过按钮时,按钮会“高亮显示” 。? Selected:构件是在一个列表中,或者是在其他类似状态,当前它是被选中的。? Insensitive:构件是“灰色” 的,不活动的,或者不响应。它不会对输入响应。状态的准确含义及其视觉表达依赖于特定构件以及当前窗口管理器的主题( T h e m e)。可以用 G T K _ W I D G E T _ S TAT

15、E ( )宏存取构件的状态。这个宏返回以下几种常量之一:G T K _ S TAT E _ N O R M A LG T K _ S TAT E _ A C T I V EG T K _ S TAT E _ P R E L I G H TG T K _ S TAT E _ S E L E C T E DG T K _ S TATE_INSENSITIVE.宏列表:状态存取函数#include G T K _ W I D G E T _ S T A T E ( w i d g e t )构件的类型转换在 G T K 中,所有构件的存储形式都是 G t k Wi d g e t,但是许多函数都需要

16、指向某种构件类型(比如 G t k B u t t o n)的指针作为参数。虽然所有的构件都是从 G t k Wi d g e t 派生而来的,但是编译器并不能理解这种派生和继承关系。为此, G T K 引进了一套类型转换系统。这些类型转换都是通过宏实现的。这些宏测试给定数据项的类型转换能力,并实现类型转换。下面几个宏是经常会碰到的:G T K _ W I D G E T ( w i d g e t )G T K _ O B J E C T ( o b j e c t )G T K _ S I G N A L _ F U N C ( f u n c t i o n )G T K _ C O N

17、 TA I N E R ( c o n t a i n e r )G T K _ W I N D O W ( w i n d o w )G T K _ B O X ( b o x )所有的构件都是从 O b j e c t 基类派生而来的,这意味着可以在任何需要一个 G t k O b j e c t 作为参数的函数中使用构件用 GTK_OBJECT() 宏将构件转换为指向 G t k O b j e c t 类型的指针就可以了。例如:gtk_signal_connect( GTK_OBJECT(butt“ co ln i) c, k e d “ ,GTK_SIGNAL_FUNC(callba

18、ck_function), callback_data);这里将 “b u t t o n”转换为一个 G t k O b j e c t 对象,并将回调函数名称转换为指向函数的指针。许多构件也是容器,它们都是从 C o n t a i n e r 内派生而来。这类构件可以用一个 G T K _ C O N TA I N E R 宏将它转换为容器,传递到需要容器指针的函数中。组装构件前面介绍了用 G t k + / G n o m e 构件编写 L i n u x 应用程序的编程思想。归纳起来就是“ 事件驱动”。也就是,用 G t k + / G n o m e 构件创建应用程序界面,然后为构

19、件的信号设置回调函数。当用户对界面进行操作时,会引发各种信号。如果某个信号,比如一个按钮的“ c l i c k e d”信号连接了回调函数,就会调用这个回调函数。通过在回调函数里面使用代码控制构件的各种属性来与用户交互,或者对内存变量进行操作,实现程序的各种功能。因而,编程的核心就归结为怎样使用构件创建界面,怎样为构件的信号设置回调函数。在 G t k +版的“Hello Wo r l d”的程序中,我们使用 gtk_container_add( )函数将按钮添加到窗口上。如果界面很复杂,不止一个按钮,怎么办呢?怎样在代码中创建构件,怎样将构件在窗口上定位呢?G T K 使用一种称为组装的方

20、法实现了这一点。G T K 是用 C 语言编写的。虽然没有使用 C + +这样的面向对象的语言, G T K 实现了自己的具有继承和派生特性的对象系统。在 G t k +构件里面,所有的构件都是从 G t k O b j e c t 对象派生而来的。每种派生构件都继承了父构件接口,同时再实现自己的一些特有功能。这样做的好处是显而易见的,既然新构件的某些功能在已有构件中已经全部具有,为什么不将这个构件直接拿来用呢?从已有构件派生一个构件,继承旧构件原有的接口,然后再实现那些旧构件不具有的接口和功能就可以创建一个新构件。在用 G t k +构件创建程序界面时,用容器实现构件的定位。在 G t k

21、+中有两种容器,它们都是抽象的 G t k C o n t a i n e r 构件的子类。第一种类型的容器构件总是由 G t k B i n (另一种抽象基类 )派生而来。G t k B i n 的派生类只能容纳一个子构件,它们为其子构件增加一些功能。例如,G t k B u t t o n 就是一种 G t k B i n,它让其子构件成为一个可接受点击的按钮。G t k F r a m e 也是一种 G t k B i n,它在其子构件周围绘制一个边框。同样, G t k Wi n d o w 让它的子构件显示在一个顶级窗口上。第二种容器构件通常是直接从 G t k C o n t a

22、i n e r 派生而来。这些构件可以有多个子构件,它们的作用就是管理布局。“ 管理布局”意味着这些容器为它们容纳的子构件分配大小尺寸和位置。例如, G t k V B o x 将它的子构件在一个垂直的栈内排列。G t k Ta b l e 构件可以让构件在一个表格上根据单元格定位。G t k F i x e d 可以将子构件放在任意坐标位置。G t k P a c k e r 允许你做 T k -风格的布局管理。实际上, G t k +中的大多数构件都是一个容器。这样也给予我们极大的灵活性。例如,如果我们想要一个带图片的按钮,因为 G t k B u t t o n 是一个容器,只需将一幅图

23、片添加到这个容器里面就可以了。对按钮中是否包含文本,文本和图片之间相对位置等都可以自由设置。使用类似的方法,可以设计出非常复杂,甚至非常古怪的外观布局。本章介绍第二种容器构件。要生成所需要的布局,并且对构件的尺寸不使用任何硬性编码,需要理解怎样使用这些容器构件。最终的目标之一是避免对窗口尺寸、屏幕尺寸、构件外观、字体等因素做任何假设。如果这些因素发生变化,应用程序应该能够自动适应。 尺寸分配一个窗口显示在屏幕上,如果用鼠标调整窗口的尺寸,窗口里面的构件会发生什么变化?这依赖于定位构件的容器构件以及构件的定位选项。窗口上的构件可能会按一定的规则改变大小。而这些规则又是通过什么方式实现的呢?这是通

24、过一种称为“ 请求”和“分配 ”的协商机制实现的。1. 请求构件的请求由宽度和高度组成:构件需要的大小尺寸。它由一个 G t k R e q u i s i t i o n 结构表示:typedef struct _GtkRequisition GtkRequisition;struct _GtkRequisitiongint16 width;gint16 height; ;不同的构件用不同的方式选择它们所需要的尺寸。例如, G t k L a b e l 构件,请求足够的尺寸用以在标签上显示所有的文本。大多数容器基于它们的子构件的尺寸请求来请求所需尺寸。例如,如果在一个 B o x 里放几个

25、按钮,B o x 会要求有足够大的空间以容纳所有的按钮。布局的第一阶段从一个顶级构件,比如说 G t k Wi n d o w,开始。因为它是一个容器,G t k Wi n d o w 询问它的子构件的尺寸要求,子构件再询问它的子构件,依此递归。当所有的子构件都被询问过后, G t k Wi n d o w 最后会从它的子构件得到一个 G t k R e q u i s i t i o n 值。这依赖于它是如何配置的,G t k Wi n d o w 也许会或者不会扩展大小以满足所有的尺寸要求。2. 分配布局的第二阶段从这一点开始。G t k Wi n d o w 对可供子构件使用的空间做出一

26、个决定,并向子构件传达这个决定。这就是子构件的尺寸分配,由以下结构表示:typedef struct _GtkAllocation GtkAllocation;struct _GtkAllocationgint16 x;gint16 y;guint16 width;guint16 height; ;w i d t h 和 h e i g h t 元素与 G t k R e q u i s i t i o n 是一样的,它们代表子构件的大小。G t k A l l o c a t i o n 结构也包含子构件相对它们父构件的坐标。G t k A l l o c a t i o n 由它们的父构件

27、容器分配给子构件。构件应该尊重传给它们的 G t k A l l o c a t i o n 值。G t k R e q u i s i t i o n 仅仅是一个请求,构件必须能够应付任何尺寸。了解了构件布局的过程,就很容易弄清楚容器在其中扮演的角色。它们的任务就是将每个构件的请求汇总成单个请求,并沿着构件树向上(按层次向上)传递,然后,将它们接收到的大小分配划分给子构件。具体怎样划分依赖于具体的容器。GtkWindow 构件前面介绍了关于构件的概念、构件的尺寸分配等。创建用户界面的目的就是将各种构件在屏幕上布局,提供一个用户与应用程序交互的接口。大多数情况下,不会将构件直接绘制在屏幕上,而

28、是绘制在一个窗口上。如果窗口的尺寸不变化,而是窗口在屏幕上移动,这些构件在窗口的相对位置一般是固定的,它们随着窗口一起移动。在 G t k / G n o m e 应用程序中, G t k Wi n d o w 构件是最大的容器。 G t k Wi n d o w 是从 G t k B i n 派生而来的,它只能容纳一个子构件。因而,要在其中容纳多个构件,必须使用 G t k B o x 、G t k Ta b l e 或者 G t k F i x e d 等构件来控制构件布局。用下面的函数创建新窗口:GtkWidget* gtk_window_new (GtkWindowType type)

29、;对于应用程序的窗口, t y p e 一般是 G T K _ W I N D O W _ TO P L E V E L。下面的函数用于设置窗口的标题:void gtk_window_set_title (GtkWindow *window,const gchar *title);其中 w i n d o w 是要设置标题的窗口, t i t l e 是一个字符串(窗口标题)。下面的函数用于设置顶级窗口在处理它的尺寸请求、以及用户调整尺寸时的行为:void gtk_window_set_policy (GtkWindow *window,gint allow_shrink,gint allow

30、_grow,gint auto_shrink);注意,不要随意使用这个函数,否则,可能会使窗口的行为变得很古怪。一般只使用下面两种调用方法:gtk_window_set_policy(GTK_WINDOW(window), FALSE, TRUE, FALSE)用户可调整窗口的尺寸。gtk_window_set_policy(GTK_WINDOW(window), FALSE, FALSE, TRUE)窗口的尺寸是由程序控制的,只与窗口的子构件的当前尺寸相匹配。第一种情况是缺省值,也就是说缺省的窗口就是这样的。下面的函数用于设置窗口是否可调整尺寸。其中 s e t t i n g 是布尔值,当

31、其值为 T R U E 时窗口尺寸可调,为 FA L S E 时窗口大小不可调整:void gtk_window_set_user_resizeable(GtkWidget* window, gboolean setting);最好只使用下面两种形式设置窗口行为。GTK+ 1.4 可能会用 g t k _ w i n d o w _ s e t _ u s e r _ r e s i z e a b l e ( ) 函数替换 g t k _ w i n d o w _ s e t _ p o l i c y ( )函数。顶级窗口总是改变自己的尺寸以保证它的子构件能够接受到它们的请求值。这意味着

32、如果添加一个子构件,顶级窗口会扩大以容纳它们。不过,如果窗口的尺寸太大,它不会自动缩小以适应子构件的尺寸请求。当 g t k _ w i n d o w _ s e t _ p o l i c y ( )函数中的 a u t o _ s h r i n k 参数设置为 T R U E、子构件的空白区域太多时,窗口将自动缩小以适应子构件的大小。 a u t o _ s h r i n k 参数通常用在上面提到的两种常见模式中的第二种。也就是说,如果想要让窗口总是根据程序的运行情况自动调整大小,将 a u t o _ s h r i n k 设置为 T R U E。注意如果 allow_shrin

33、k 和 allow_grow 参数都设置为 FALSE,auto_shrink 参数没有任何作用。前面提到的两种情况都没有将 a l l o w _ s h r i n k 参数设置为 T R U E。如果 a l l o w _ s h r i n k 设置为 T R U E,用户能够缩小窗口的尺寸,使它的子构件不能接收到全部的尺寸请求。通常这是一个糟糕的主意,因为这样将使大多数构件的外观显示不正确。此外,如果由于某种原因,窗口的尺寸得到重新计算, G T K +倾向于重新扩展窗口。因而, a l l o w _ s h r i n k 参数应该总设置为 FA L S E。使用 a l l

34、o w _ s h r i n k 时,存在的实际问题是一些特殊构件总是需要太多的空间,所以用户不能充分缩小窗口的大小。也许应该对子构件调用 g t k _ w i d g e t _ s e t _ u s i z e ( )函数,并迫使它的尺寸请求足够大。最好的办法是调用 g t k _ w i n d o w _ s e t _ d e f a u l t _ s i z e ( )函数设置构件的缺省尺寸,以便子构件获得比它请求的值更大的分配值。void gtk_window_set_default_size (GtkWindow *window,gint width,gint heig

35、ht);其中 w i d t h 和 h e i g h t 是要设置的窗口的缺省宽度和高度。用下面的构件向窗口中添加子构件:gtk_container_add (GTK_CONTAINER (window), widget);窗口最常用的两个信号是 d e l e t e _ e v e n t 和 d e s t r o y。当使用窗口管理器关闭窗口(点击窗口标题条上的“”按钮),或者在窗口的某个构件上调用 g t k _ w i d g e t _ d e s t r o y ( )函数时,将引发 d e l e t e _ e v e n t 信号。如果在 d e l e t e _

36、e v e n t 信号处理函数中返回 FA L S E,G T K 将引发 d e s t r o y 信号。返回 T R U E 意味着不需要销毁窗口。对某些窗口,比如对话框,一般不在 d e l e t e _ e v e n t 信号中销毁窗口。返回 FA L S E,窗口会被信号销毁。一般应该为窗口的 d e l e t e _ e v e n t 信号设置一个回调函数,对该信号进行处理。否则,只要用户点击窗口标题条上的“”按钮,窗口就会关闭。GtkBox有两种 G t k B o x(组装盒): G t k H B o x(水平组装盒)和 G t k V B o x(垂直组装盒)。

37、一个 G t k B o x 可以管理一行( G t k H B o x )或一列( G t k V B o x )构件。对 G t k H B o x 来说,所有的构件都分配了同样的高度,组装盒的作用就是在构件间分配可用空间。G t k H B o x 还随意用一些可用宽度在构件间预留间隙(称为“ 间距” )。G t k V B o x 的作用是一样的,不过是在垂直的方向上(也就是,它分配可用的高度而不是宽度) 。G t k B o x 是一个抽象的基类, G t k V B o x 和 G t k H B o x 差不多可以完全使用它的接口。组装盒是最有用的容器构件。用下面函数列表中的构建

38、函数创建新的 G t k B o x 。组装盒构建函数带两个参数。homogeneous 参数如果为 T R U E(同质),意味着所有的子构件都被分配同样数量的空间。s p a c i n g 参数指定每个子构件之间的间距。组装盒创建之后,还有函数可以改变 s p a c i n g 参数值,切换构件的同质属性。函数列表: G t k H B o x 构建函数#include GtkWidget* gtk_hbox_new(gboolean homogeneous,gint spacing)函数列表: G t k V B o x 构建函数#include GtkWidget* gtk_vbo

39、x_new(gboolean homogeneous,gint spacing)有两个基本的函数添加子构件到组装盒中,下面的函数列表中已将它们列出。函数列表: 在 G t k B o x 中添加构件#include void gtk_box_pack_start(GtkBox* box,GtkWidget* child,gboolean expand,gboolean fill,gint padding)v o i dgtk_box_pack_end(GtkBox* box,GtkWidget* child,gboolean expand,gboolean fill,gint padding)

40、一个组装盒可以包含两套构件。第一套是从组装盒的“ 头部” (顶部或左边) 组装的;第二种是从“尾部”(底部或者右边)开始组装。如果将三个构件从盒子的“头部”开始组装到盒子里,组装的第一个构件会出现在盒子的最上面或者最左边,第二个构件紧接着第一个构件,第三个最接近盒子的中心。如果接着将三个按钮组从组装盒的“尾部”组装到盒子里,第一个出现在盒子的最下边或者最右边,第二个紧挨着它,第三个最靠近盒子的中心。所有六个构件都组装之后,从上到下或者从左到右的次序是: 1,2,3,3,2 ,1。图 4 - 1 显示了这个例子。组装次序只对盒子的每个末端是重要的,也就是,可以使用不同的组装方法,取得相同的结果。

41、图 4-1 组装到 GtkVBox 中的按钮1 GtkBox 布局细节组装过程受三个参数影响,它们对从 “头部” 和“尾部”组装都是一样的。这些参数的含义很复杂,因为它们与盒子的 homogeneous 设置以及每个构件相互作用。下面介绍 G t k B o x 怎样计算它的相关“方向” (对 G t k H B o x 是 w i d t h,对 G t k V B o x 是 h e i g h t )上的尺寸请求:1) 每个子构件的总尺寸请求等于每个子构件的尺寸请求加上两倍用于组装子构件的填充量值。子构件的填充量是在子构件两边的空白空间。简而言之,子构件尺寸= (子构件的尺寸请求)2(

42、子构件的填充量)。2) 如果盒子是同质的,整个盒子的基准尺寸请求等于最大的子构件尺寸请求(请求数 填充量)乘以子构件的数目。在同质的盒子中,所有的子构件都与最大的子构件一样大的。 3) 如果盒子不是同质的,整个盒子的基准尺寸请求等于每个子构件的尺寸请求 (请求数填充量)之和。4) 组装盒范围内的 s p a c i n g (间距)设置决定在子构件之间留多大的间距,所以这个值要乘以子构件数目减 1,并加到基准尺寸请求中。注意,间距并不属于子构件,它是子构件之间的空白空间,不受 e x p a n d 和 f i l l 参数的影响。另一方面, p a d d i n g (填充量) 是环绕每个

43、子构件的空间,受子构件的组装参数的影响。5) 所有的容器都有一个“边框宽度 ”设置;它会将两倍的边框宽度(代表两边的边框宽度) 加到尺寸请求中。这样, G t k B o x 的总的尺寸请求就是: (子构件尺寸之和)s p a c i n g(子构件数1 )2(边框宽度)。在计算它的尺寸请求,将请求传送到它的父容器中之后, G t k B o x 会接收到它的尺寸分配 ,并将尺寸按下面的规则在子构件之间分配:1) 边框宽度和构件间的间距从分配值中减去,剩余的部分是子构件自己的可用空间。这块空间分为两块:子构件实际要求的数量(子构件的请求值和填充量) ,以及“额外空间”。额外空间= (分配尺寸)

44、 (子构件尺寸之和)。2) 如果盒子不是同质的,“额外”空间在按 e x p a n d 参数设置为 T R U E 时在子构件之间划分。这些子构件会占满可用空间。如果没有子构件能够展开,额外空间将用于在盒子中央(在从头组装和从尾部组装的构件之间)增加更多的空间。3) 如果盒子是同质的,额外空间根据需要分配。那些请求较多空间的构件将得到较少的额外空间,让每个构件都占据同样的空间。同质的组装盒忽略 e x p a n d 参数- - -额外空间分配给所有的子构件,而不是可扩展的构件。4) 当构件获得一些额外空间时,有两种可能。在子构件周围增加更多的填充量,或者将子构件本身扩展。f i l l 参

45、数决定哪种可能会发生。如果 f i l l 是 T R U E,子构件展开填充空间- - -也就是,整个空间变成子构件的分配值;如果 f i l l 是 FA L S E,增加子构件的填充量,填满额外空间,只给子构件分配它请求的空间。注意,如果 e x p a n d 设置为 FA L S E 并且盒子也不是同质的,f i l l 没有效果,因为子构件永远也不会接受到额外空间。G t k +教程的作者将这么多的设置归纳为 5 种情形,下面我们一步一步看。2. 非同质组装盒的组装模式在非同质的组装盒中有三种组装方法。第一种,将所有的构件用它们的正常尺寸组装到盒子的尾部。这意味着将 e x p a

46、 n d 参数设置为 FA L S E:g t k _ b o x _ p a c k _ s t a r t ( G T K _ B O X ( b o x ) ,child,FALSE, FALSE, 0);结果显示在图 4 - 2 中。在这里,只有 e x p a n d 参数管用,没有子构件会接受额外空间,所以即使 f i l l 设置为 T R U E 它们也不能充满剩余空间。图 4-2 非同质,expand = FALSE第二种方法,可以在 G t k B o x 中扩展构件,让它们保持它们的正常尺寸,如图 4 - 3 所示,这意味着将 e x p a n d 参数设置为 T R

47、U E:g t k _ b o x _ p a c k _ s t a r t ( G T K _ B O X ( b o x ) ,child,TRUE, FALSE, 0);图 4-3 非同质,expand = TRUE 和 fill = FALSE最后,可以将 f i l l 参数设置为 T R U E,在盒子中填充构件 (让最大的子构件有更大的空间):g t k _ b o x _ p a c k _ s t a r t ( G T K _ B O X ( b o x ) ,child,TRUE, TRUE, 0);这种设置的效果见图 4 - 4。图 4-4 非同质,expand =

48、TRUE 和 fill = TRUE3. 同质 G t k B o x 组装模式组装一个同质的 G t k B o x 只有两种有意义的方法。 e x p a n d 参数是与同质的 G t k B o x 是无关的,所以这两种情况是对应于 f i l l 参数的不同设置。如果 f i l l 是 FA L S E,将会得到图 4 - 5 的结果。注意,组装盒逻辑划分为三个部分,但是只有最大的子构件才占据了它的整个空间。其他构件只填满了空间的三分之一。如果 f i l l 是 T R U E,将得到图 4 - 6 所示的结果,所有的构件都是一样大的。图 4-5 同质的 GtkBox,fill

49、= FALSE图 4-6 同质的 G t k B o x,fill = TRUE4. 组装摘要图 4 - 7 同时显示了 5 种组装技巧。它们都是组装到一个同质的 G t k V B o x 中,f i l l 设置为 T R U E,构件之间的间距是两个像素。从这应该能够理解它们的相对效果。要记住,还可以改变p a d d i n g 和 s p a c i n g 参数来增加或减少构件之间的空白空间。最后一点:注意 e x p a n d 和 f i l l 参数只在盒子的尺寸比它要求的尺寸大时才有用。也就是说,这些参数决定额外的空间如何分配。典型情况下,当用户调整窗口的尺寸,让它比缺省尺寸大时,额外空间才显示出来。因而,应该尽量尝试调整窗口的尺寸,以保证构件是正确组装的。图 4-7 五种用组装盒组装构件的方法表格构件 GtkTableG t k Ta b l e(表格构件)是很常用的用于定位的构件。我们用表格构件创建一个网格,把构件放在网格里。构件可以在网格中占据任意多个格子。用 g t k _ t a b l e _ n e w 创建一个表格构件:GtkWidget *gtk_table_new( gint rows,gint columns,gint homogeneous);第一个参数是表格的行数,第二个参数是表格的列数。h

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报