GTK 中的层次关系
(点击 上方公众号 ,可快速关注)
层次是指系统在结构或功能方面的等级秩序,关系是不同事物之间的联系。GTK是一个GUI框架,在界面中,很明显能感觉到层次,如,窗口中的Widget,我们能得到窗口和Widget是包含关系。而且,GUI在面向对象领域研究较为成熟,这也是当前几乎所有成熟的GUI框架采用面向对象实现的原因,面向对象当然也有一些层次关系,如,基类和子类。
本篇文章主要介绍以下层次关系:
-
Parent和Child
-
Base-class和Sub-class
-
接口与实现
以下分别说明。
Parent和Child
这涉及到 容器 ( container )的概念,简单来说,容器就是能“盛放”其他widget的widget。假设widget B 能盛放widget A ,则 A 就是一个容器,我们称 A 是 Parent , B 是 A 的 Child 。虽然各个框架对其的叫法不同,但原理是相通的。
在使用GUI框架编写界面的过程中,大部分工作其实就是选择合适的容器,然后在容器里放入不同的Widget,在构造复杂的界面的过程中,可能会涉及到递归,如,在容器里嵌套容器。
在GTK中已经内建了很多容器,如下图,选择合适的容器是快速构建美观的界面所必不可少的。后续会对常用的容器的逐一介绍。
Base-class和Sub-class
前面提到过,GTK是面向对象的,这不可避免得会涉及到面向对象的继承关系,在GTK里关系的发起对象称之为 基类 ( base-class ),关系的结束对象称之为 子类 ( sub-class ),例如:
在上面的类层次结构里, GtkWindow
基类有6个子类。特别说明,GTK中的继承属于单继承。
假设我们有一个 GtkDialog
的对象 dialog
,要设置默认大小,我们知道其基类 GtkWindow
有一个成员函数 gtk_window_set_default_size
可以实现该功能。在C++或其他内置面向对象的语言,可能的代码会:
dialog->gtk_window_set_default_size(width, height);
但GTK是基于C语言实现的面向对象系统,少了一些语法糖,写起来相对麻烦点:
gtk_window_set_default_size(GTK_WINDOW(dialog), width, height);
上面使用了 GTK_WINDOW
宏做了转换,每个类都有对应的宏,类和对应的宏的关系比较显而易见。
在面向对象里都有这个概念,本篇文章不多赘余。
接口与实现
接口 (interface)这个概念类似于Java中的 Interface ,其声明了一组通用的Api,其 实现 类需要实现定义的每个函数。类是可以实现多个接口的,这跟Java中的接口规则也类似。
比如, GtkEntry
实现了 AtkImplementorIface
、 GtkBuildable
、 GtkEditable
和 GtkCellEditable接口。
实现类的对象在调用接口中的函数时也面临着和基类、子类同样的问题,可以使用同样的方式解决:
gtk_editable_select_region(GTK_EDITABLE(entry), start_pos, end_pos);
上面的示例是 GtkEntry
对象 entry
选择文字某个区域的代码,可以看到接口也有对应的宏。