下载一个gtk,directfb源码,
就可以分析出其复杂的饶人的重绘过程。
不少用GTK做程序的人,知道用gtk_widget_show_all来显示,内部的现实过程如果比较清楚,分析问题的能力应该会好点。
程序都是调用这个接口:
void gtk_widget_show_all (GtkWidget *widget) { GtkWidgetClass *class;
g_return_if_fail (GTK_IS_WIDGET (widget));
if ((GTK_WIDGET_FLAGS (widget) & GTK_NO_SHOW_ALL) != 0) return;
class = GTK_WIDGET_GET_CLASS (widget);
if (class->show_all) class->show_all (widget); } |
获取其class,然后调用其注册的show_all函数:
static void gtk_widget_class_init (GtkWidgetClass *klass) { …… klass->show = gtk_widget_real_show; klass->show_all = gtk_widget_show; klass->hide = gtk_widget_real_hide; klass->hide_all = gtk_widget_hide; klass->map = gtk_widget_real_map; klass->unmap = gtk_widget_real_unmap; klass->realize = gtk_widget_real_realize; klass->unrealize = gtk_widget_real_unrealize; |
把一个widget设置为可见,并且发送SHOW信号出去
void gtk_widget_show (GtkWidget *widget) { if (!GTK_WIDGET_VISIBLE (widget)) { g_object_ref (widget); if (!GTK_WIDGET_TOPLEVEL (widget)) gtk_widget_queue_resize (widget); g_signal_emit (widget, widget_signals[SHOW], 0); g_object_notify (G_OBJECT (widget), "visible"); g_object_unref (widget); } } |
看这个SHOW信号的回调:
klass->show = gtk_widget_real_show;
static void gtk_widget_real_show (GtkWidget *widget) { if (!GTK_WIDGET_VISIBLE (widget)) { GTK_WIDGET_SET_FLAGS (widget, GTK_VISIBLE);
if (widget->parent && GTK_WIDGET_MAPPED (widget->parent) && GTK_WIDGET_CHILD_VISIBLE (widget) && !GTK_WIDGET_MAPPED (widget)) gtk_widget_map (widget); } } |
void gtk_widget_map (GtkWidget *widget) { g_return_if_fail (GTK_IS_WIDGET (widget)); g_return_if_fail (GTK_WIDGET_VISIBLE (widget)); g_return_if_fail (GTK_WIDGET_CHILD_VISIBLE (widget));
if (!GTK_WIDGET_MAPPED (widget)) { if (!GTK_WIDGET_REALIZED (widget)) gtk_widget_realize (widget);
g_signal_emit (widget, widget_signals[MAP], 0);
if (GTK_WIDGET_NO_WINDOW (widget)) gdk_window_invalidate_rect (widget->window, &widget->allocation, FALSE); } } |
如果一个