看看GtkWindow如何被生出来的.
用Glib/GObject/Gtk也有很长时间了,没有时间往下刨根,现在刨一刨。
再展开GtkContainer的定义://不用展开,直接定义的
看看GObject的定义:gtk_init()后,这个对象是已经建立了
下面我们来跟着一下其流程:(步步跟踪其父类,如果父类还没有创建,则先创建父类)
GtkObject对象存在了,那就看它的子类吧:GtkWidget
接着往下搞:GtkWidget对象也有了,在往下看子类:GtkContainer
上面仅仅是一些对象,那这些对象携带的回调函数都是从哪里调用的呢?
上面的递归调用会调用函数type_class_init_Wm()完成对某个类的初始化,即,分配内存同时调用class_init()
3 gtk_widget_base_class_init 是NULL所以不调用
4 gtk_container_base_class_init
5 gtk_bin, gtk_windonw的base_class_init()都是NULL
1 定义GtkWindow
G_DEFINE_TYPE_WITH_CODE (GtkWindow, gtk_window, GTK_TYPE_BIN, G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE, gtk_window_buildable_interface_init)) |
2 展开它:
在gtype.h中定义如下宏:
#define G_DEFINE_TYPE_WITH_CODE(TN, t_n, T_P, _C_) _G_DEFINE_TYPE_EXTENDED_BEGIN (TN, t_n, T_P, 0) {_C_;} _G_DEFINE_TYPE_EXTENDED_END()
#define _G_DEFINE_TYPE_EXTENDED_BEGIN(TypeName, type_name, TYPE_PARENT, flags) / / static void type_name##_init (TypeName *self); / static void type_name##_class_init (TypeName##Class *klass); / static gpointer type_name##_parent_class = NULL; / static void type_name##_class_intern_init (gpointer klass) / { / type_name##_parent_class = g_type_class_peek_parent (klass); / type_name##_class_init ((TypeName##Class*) klass); / } / / GType / type_name##_get_type (void) / { / static volatile gsize g_define_type_id__volatile = 0; / if (g_once_init_enter (&g_define_type_id__volatile)) / { / GType g_define_type_id = / g_type_register_static_simple (TYPE_PARENT, / g_intern_static_string (#TypeName), / sizeof (TypeName##Class), / (GClassInitFunc) type_name##_class_intern_init, / sizeof (TypeName), / (GInstanceInitFunc) type_name##_init, / (GTypeFlags) flags); / { /* custom code follows */ #define _G_DEFINE_TYPE_EXTENDED_END() / /* following custom code */ / } / g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); / } / return g_define_type_id__volatile; / } /* closes type_name##_get_type() */ |
把定义的宏展开:
static void gtk_window_init (GtkWindow *self); static void gtk_window_class_init (GtkWindowClass * klass); static void gtk_window_parent_class = NULL; static void gtk_window_class_intern_init (gpointer klass) { gtk_window_parent_class = g_type_class_peek_parent (klass); gtk_window_class_init ((GtkWindowClass*) klass); }
GType gtk_window_get_type (void) { static volatile gsize g_define_type_id__volatile = 0; if (g_once_init_enter (&g_define_type_id__volatile)) { GType g_define_type_id = g_type_register_static_simple (GTK_TYPE_BIN, //父亲 g_intern_static_string ("GtkWindow"), sizeof (GtkWindowClass), (GClassInitFunc) gtk_window_class_intern_init, sizeof (GtkWindow), (GInstanceInitFunc) gtk_window_init, 0); { const GInterfaceInfo g_implement_interface = { (GInterfaceInitFunc) gtk_window_buildable_interface_init, NULL, NULL };
g_type_add_interface_static (g_define_type_id, GTK_TYPE_BUILDABLE, &g_implement_interface); } g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); } return g_define_type_id__volatile; } |
再把GtkBin的定义展开:
G_DEFINE_ABSTRACT_TYPE (GtkBin, gtk_bin, GTK_TYPE_CONTAINER)
static void gtk_bin_init (GtkBin *self); static void gtk_bin_class_init (GtkBinClass * klass); static void gtk_bin_parent_class = NULL; static void gtk_bin_class_intern_init (gpointer klass) { gtk_bin_parent_class = g_type_class_peek_parent (klass); gtk_bin_class_init ((GtkBinClass*) klass); }
GType gtk_bin_get_type(void) { static volatile gsize g_define_type_id__volatile = 0; if (g_once_init_enter (&g_define_type_id__volatile)) { GType g_define_type_id = g_type_register_static_simple (GTK_TYPE_CONTAINER, //GtkBin的父亲 g_intern_static_string ("GtkBin"), sizeof (GtkBinClass), (GClassInitFunc) gtk_bin_class_intern_init, sizeof (GtkBin), (GInstanceInitFunc) gtk_bin_init, G_TYPE_FLAG_ABSTRACT); { } g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); } return g_define_type_id__volatile; } |
再展开GtkContainer的定义://不用展开,直接定义的
#define GTK_TYPE_CONTAINER (gtk_container_get_type ())
/* --- functions --- */ GType gtk_container_get_type (void) { static GType container_type = 0;
if (!container_type) { const GTypeInfo container_info = { sizeof (GtkContainerClass), (GBaseInitFunc) gtk_container_base_class_init, (GBaseFinalizeFunc) gtk_container_base_class_finalize, (GClassInitFunc) gtk_container_class_init, NULL /* class_finalize */, NULL /* class_data */, sizeof (GtkContainer), 0 /* n_preallocs */, (GInstanceInitFunc) gtk_container_init, NULL, /* value_table */ };
static const GInterfaceInfo buildable_info = { (GInterfaceInitFunc) gtk_container_buildable_init, NULL, NULL };
container_type = g_type_register_static (GTK_TYPE_WIDGET, //GtkContainer的父亲 I_("GtkContainer"), &container_info, G_TYPE_FLAG_ABSTRACT);
g_type_add_interface_static (container_type, GTK_TYPE_BUILDABLE, &buildable_info);
}
return container_type; } |
GtkWidget的get_type()也是直接定义的
/* --- functions --- */ GType gtk_widget_get_type (void) { static GType widget_type = 0;
if (G_UNLIKELY (widget_type == 0)) { const GTypeInfo widget_info = { sizeof (GtkWidgetClass), NULL, /* base_init */ (GBaseFinalizeFunc) gtk_widget_base_class_finalize, (GClassInitFunc) gtk_widget_class_init, NULL, /* class_finalize */ NULL, /* class_init */ sizeof (GtkWidget), 0, /* n_preallocs */ (GInstanceInitFunc) gtk_widget_init, NULL, /* value_table */ };
const GInterfaceInfo accessibility_info = { (GInterfaceInitFunc) gtk_widget_accessible_interface_init, (GInterfaceFinalizeFunc) NULL, NULL /* interface data */ };
const GInterfaceInfo buildable_info = { (GInterfaceInitFunc) gtk_widget_buildable_interface_init, (GInterfaceFinalizeFunc) NULL, |