(点击上方公众号,可快速关注)
层次是指系统在结构或功能方面的等级秩序,关系是不同事物之间的联系。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
选择文字某个区域的代码,可以看到接口也有对应的宏。