Chinaunix首页 | 论坛 | 博客
  • 博客访问: 9417367
  • 博文数量: 1748
  • 博客积分: 12961
  • 博客等级: 上将
  • 技术积分: 20070
  • 用 户 组: 普通用户
  • 注册时间: 2009-01-09 11:25
个人简介

偷得浮生半桶水(半日闲), 好记性不如抄下来(烂笔头). 信息爆炸的时代, 学习是一项持续的工作.

文章分类

全部博文(1748)

文章存档

2024年(24)

2023年(26)

2022年(112)

2021年(217)

2020年(157)

2019年(192)

2018年(81)

2017年(78)

2016年(70)

2015年(52)

2014年(40)

2013年(51)

2012年(85)

2011年(45)

2010年(231)

2009年(287)

分类: Android平台

2017-12-21 19:50:33

GTK3 下自定义类(可模拟Application/Window/其他Widget)


主要参考 http://blog.csdn.net/taiyang1987912/article/details/49026183
例程参考 gtk3-demo的 list box


#####################################################################################
步骤一: 定义类型
例如:
G_DEFINE_TYPE (MyMessage, my_message, G_TYPE_OBJECT);


其中第三个参数 (G_TYPE_OBJECT/GTK_TYPE_APPLICATION/GTK_TYPE_LIST_BOX_ROW/GTK_TYPE_WINDOW等等)用于表明父类的类型,在需要继承其他的类时特别重要.
第一个参数为自定义类型名, 每个单词的首字母要大写. 
第二个参数为自定义类型名, 每个单词的首字母要小写且单词间隔用_下划线.


这个宏 其中包括(*代表小写类型名,即第二个参数*_init、*_class_init的声明*_class_intern_init、*_get_type的定义,还有一个静态全局变量*_parent_class的声明
其实扩展开就是  G_DEFINE_TYPE_EXTENDED , 在 glib.h中有完整定义.

举例:
G_DEFINE_TYPE (MyCustom, my_custom, G_TYPE_OBJECT);
此时需要定义大写的类名,确切说时结构体(GTK承续的C风格)


#####################################################################################
步骤二: 实现类型以及声明的函数
typedef struct {
    GObject parent; ////第一个域必须时父类型, 且成员名建议为 parent
    //扩展的私有数据类型定义, 可以为 GTK 的控件
} MyCustom;


typedef struct {
    GObjectClass parent_class; //第一个域必须时父类型类名, 且成员名建议为 parent_class
} MyCustomClass; //注意此处为大写类型名后加入Class


#define MY_TYPE_CUSTOM   (my_custom_get_type ())  //直接利用 G_DEFINE_TYPE 宏中已经完成的 my_custom__get_type()的定义. 返回自定义类型
#define MY_CUSTOM(obj)   (G_TYPE_CHECK_INSTANCE_CAST ((obj), MY_TYPE_CUSTOM, MyCustomClass)) //如果obj是MY_TYPE_CUSTOM对象, 则转换为MyCustomClass的指针.
#define MY_CUSTOM_CLASS(klass)   (G_TYPE_CHECK_CLASS_CAST ((klass), MY_TYPE_CUSTOM, MyCustomClass)) //如果klass是MY_TYPE_CUSTOM类, 则返回MyCustomClass类指针
#define MY_IS_CUSTOM(obj)   (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MY_TYPE_CUSTOM)) //检查对象是否时自定义类型的对象
#define MY_IS_CUSTOM_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), MY_TYPE_CUSTOM)) //检查类 klass 是否是自定义类的继承类
#define MY_CUSTOM_GET_CLASS(obj)         (G_TYPE_INSTANCE_GET_CLASS ((obj), MY_TYPE_CUSTOM, MyCustomClass)) //返回自定义类的结构体指针


*_class_init函数对每个类只会调用一次,class结构对每个类来说也只有一个副本,这个函数有两个作用:一是对class结构中的域进行初始化,二是注册该类的属性、信号、私有数据
2.1 实现 G_DEFINE_TYPE 宏预定义的 *_class_init  *_init


//类结构初始化
void my_custom_class_init (MyCustomClass *klass)  //函数名 --> G_DEFINE_TYPE宏中参数二_class_init. 参数类型为大写类型名,即G_DEFINE_TYPE宏中第一个参数
{
    GObjectClass *object_class = G_OBJECT_CLASS (klass); //针对此对象, 可以设置此类对象的各种参数和函数调用.
    object_class->finalize = my_custom_finalize; //此项时必要的, 用于释放私有资源.
    //绑定类和UI. 
    /* 
        GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
        gtk_widget_class_set_template_from_resource (widget_class, "/ui/my.ui");
        gtk_widget_class_bind_template_child_private (widget_class, MyCustom, content_label);
     */
}


void my_custom_finalize(GObject *obj) //参数类型为父类型类名
{
    MyCustom *msg = MY_CUSTOM (obj);
    //开始 释放私有资源
    G_OBJECT_CLASS (my_custom_parent_class)->finalize (obj); //调用父类的finalize.
}


void my_custom_init (MyCustom *obj)  //初始化实例结构
{
    //如果通过 G_DEFINE_TYPE_WITH_PRIVATE 定义, 那么还可以通过预定义 my_custom_get_instance_private(obj)获得除了 parent域之外的私有资源的指针
    obj->priv = my_custom_get_instance_private(obj);
    //初始化私有资源, 或者调用 gtk_widget_init_template(GTK_WIDGET (obj)) 来绑定控件和事件回调
}




阅读(2629) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~