Skip to content

4. 使用继承实现自定义控件

在使用 AWTK 进行 UI 设计的时候,可能会出现某些控件的功能只能够满足一部分需求,这种时候就可以使用继承来创建一个自定义控件,本章将以 usb_camera 为例讲解如何通过继承实现一个自定义控件。关于如何完整地开发一个自定义控件请参考 开发自定义控件 章节,本章只介绍继承实现与普通实现的区别,不做具体的实现流程介绍。

4.1 完成自定义控件的定义

c
typedef struct _usb_camera_t {
  /* 继承的类 */
  mutable_image_t base;
  /* 子类自身特有属性定义 */
  ....

} usb_camera_t;

以上为 usb_camera 控件结构体定义的一部分,usb_camera 类继承自 mutable_image 类,所以在定义时需要将 mutable_image 类作为结构体的第一项。需要注意的是,只能进行单继承,不允许多继承。

4.2 完成自定义控件的虚表结构体定义

以 usb_camera 为例,它的虚表结构体定义如下所示,其中与普通自定义控件不同的是 get_parent_vt 属性,该属性在填写时请按照以下格式,将父类控件名称填写上。

c
TK_DECL_VTABLE(usb_camera) = {.size = sizeof(usb_camera_t),
                              .type = WIDGET_TYPE_USB_CAMERA,
                              .clone_properties = s_usb_camera_properties,
                              .persistent_properties = s_usb_camera_properties,
                              /* 获取父类虚表结构体 */
                              .get_parent_vt = TK_GET_PARENT_VTABLE(mutable_image),
                              .create = usb_camera_create,
                              .on_paint_self = usb_camera_on_paint_self,
                              .set_prop = usb_camera_set_prop,
                              .get_prop = usb_camera_get_prop,
                              .on_event = usb_camera_on_event,
                              .on_destroy = usb_camera_on_destroy};

4.3 实现自定义控件的创建与销毁函数

以 usb_camera 控件的创建函数与销毁函数为例,在创建函数结束前调用父类的初始化函数,在销毁函数结束前调用父类的销毁函数。

c
/* 控件的创建函数 */
widget_t *usb_camera_create(widget_t *parent, xy_t x, xy_t y, wh_t w, wh_t h) {
  widget_t *widget =
      widget_create(parent, TK_REF_VTABLE(usb_camera), x, y, w, h);
  usb_camera_t *usb_camera = USB_CAMERA(widget);
  return_value_if_fail(usb_camera != NULL, NULL);
  /* 子类的初始化过程 */
  ......
  /* 父类的初始化函数 */
  mutable_image_init(widget);
  return widget;
}
/* 控件的销毁函数 */
static ret_t usb_camera_on_destroy(widget_t *widget) {
  usb_camera_t *usb_camera = USB_CAMERA(widget);
  return_value_if_fail(usb_camera != NULL, RET_BAD_PARAMS);
  /* 子类的销毁过程 */
  ......
  /* 父类的销毁函数 */
  return mutable_image_on_destroy(widget);
}

4.4 实现自定义控件的其他函数

关于其他自定义控件需要实现的函数,请参考 开发自定义控件 章节,本章就不再赘述,在其他的函数里用户也可以按需使用父类的各种函数来简化子类的函数实现。