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) |