gtk_widget_set_realize()的作用是什么,什么时候要用到

laibaohua 2008-08-27 07:58:07
如题
在下面的代码中,好像有无gtk_widget_realize(dialog);运行的结果都一样?这是为什么
#include <gtk/gtk.h>
#include <glib.h>

GtkWidget *close_button;
GtkWidget *text_button;
GtkWidget *icon_button;
GtkWidget *both_button;
GtkWidget *tooltips_button;
void radio_event(GtkWidget* widget,gpointer data)
{
if(GTK_TOGGLE_BUTTON(text_button)->active)
gtk_toolbar_set_style(GTK_TOOLBAR(data),GTK_TOOLBAR_TEXT);
if(GTK_TOGGLE_BUTTON(icon_button)->active)
gtk_toolbar_set_style(GTK_TOOLBAR(data),GTK_TOOLBAR_ICONS);
if(GTK_TOGGLE_BUTTON(both_button)->active)
gtk_toolbar_set_style(GTK_TOOLBAR(data),GTK_TOOLBAR_BOTH);
}

void toggle_event(GtkWidget *widget,gpointer data)
{
gtk_toolbar_set_tooltips(GTK_TOOLBAR(data),
GTK_TOGGLE_BUTTON(widget)->active);
}

int main(int argc,char *argv[])
{
GtkWidget* dialog;
GtkWidget* handlebox;

GtkWidget *toolbar;
GtkWidget *iconw;

gtk_init(&argc,&argv);
dialog = gtk_dialog_new();
gtk_window_set_title(GTK_WINDOW(dialog),"GTKToolbar Tutorial");
gtk_widget_set_size_request(GTK_WIDGET(dialog),600,300);
GTK_WINDOW(dialog)->allow_shrink = TRUE;
g_signal_connect(G_OBJECT(dialog),"delete_event",
G_CALLBACK(gtk_main_quit),NULL);
// gtk_widget_realize(dialog);

handlebox = gtk_handle_box_new();
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
handlebox,FALSE,FALSE,5);
toolbar = gtk_toolbar_new();
gtk_toolbar_set_orientation(GTK_TOOLBAR(toolbar),GTK_ORIENTATION_HORIZONTAL);
gtk_toolbar_set_style(GTK_TOOLBAR(toolbar),GTK_TOOLBAR_BOTH);
gtk_container_set_border_width(GTK_CONTAINER(toolbar),5);
gtk_toolbar_set_space_size(GTK_TOOLBAR(toolbar),5);
gtk_container_add(GTK_CONTAINER(handlebox),toolbar);
iconw = gtk_image_new_from_file("gtk.xpm");
close_button =
gtk_toolbar_append_item(GTK_TOOLBAR(toolbar),
"Close",
"Close this app",
"private",
iconw,
GTK_SIGNAL_FUNC(gtk_main_quit),
NULL);
gtk_toolbar_append_space(GTK_TOOLBAR(toolbar));

iconw = gtk_image_new_from_file("gtk.xpm");
icon_button = gtk_toolbar_append_element(
GTK_TOOLBAR(toolbar),
GTK_TOOLBAR_CHILD_RADIOBUTTON,
NULL,
"Icon",
"Only icons in toolbar",
"private",
iconw,
GTK_SIGNAL_FUNC(radio_event),
toolbar);
gtk_toolbar_append_space(GTK_TOOLBAR(toolbar));


iconw = gtk_image_new_from_file("gtk.xpm");
text_button = gtk_toolbar_append_element(
GTK_TOOLBAR(toolbar),
GTK_TOOLBAR_CHILD_RADIOBUTTON,
icon_button,
"Text",
"Only Text in toolbar",
"private",
iconw,
GTK_SIGNAL_FUNC(radio_event),
toolbar);
gtk_toolbar_append_space(GTK_TOOLBAR(toolbar));

iconw = gtk_image_new_from_file("gtk.xpm");
both_button = gtk_toolbar_append_element(
GTK_TOOLBAR(toolbar),
GTK_TOOLBAR_CHILD_RADIOBUTTON,
text_button,
"Both",
"Both in toolbar",
"private",
iconw,
GTK_SIGNAL_FUNC(radio_event),
toolbar);
gtk_toolbar_append_space(GTK_TOOLBAR(toolbar));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(both_button),TRUE);


iconw = gtk_image_new_from_file("gtk.xpm");
tooltips_button = gtk_toolbar_append_element(
GTK_TOOLBAR(toolbar),
GTK_TOOLBAR_CHILD_TOGGLEBUTTON,
NULL,
"Tooltips",
"Show tooltips",
"private",
iconw,
GTK_SIGNAL_FUNC(toggle_event),
toolbar);
gtk_toolbar_append_space(GTK_TOOLBAR(toolbar));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tooltips_button),TRUE);

gtk_widget_show(toolbar);
gtk_widget_show(handlebox);
gtk_widget_show(dialog);
gtk_main();
return 0;
}

还有一个问题就是在编译的时候出现(.text+0x2bc): undefined reference to `gtk_toolbar_set_space_size'
collect2: ld 返回 1
不知道是什么错误?
...全文
500 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
morris88 2009-05-01
  • 打赏
  • 举报
回复
1、gtk_widget_realize的作用是,为构件(widget)创建一个gdk_window,也即是为widget创建一个xid资源


2、只有当一个widget已经被加入到顶级窗口后(top-level),才可以对widget调用gtk_widget_realize操作,这是因为gdk_window的创建,是需要首先创建父窗口,再才创建子窗口的。因此,这是一个从root_window依序往下,创建窗口的过程。如果程序中,还没有对所有的widget连接好(确定父子关系),就擅自对其中某个widget调用gtk_widget_realize操作,那么会导致严重的后果,因为可能导致某个widget的父窗口为null,或自身的widget->window为null。


3、对某个widget调用gtk_widget_realize操作,这不仅仅只是自身的widget被realized。整个的过程是,从top_level的widget开始,依次realize每个级别上的widget。也即,所有的父widget都会被realized,因为gdk_window的创建,需要父窗口先被创建出来。


4、gtk_widget_realize一般是不被外部程序所调用(虽然gtk_widget_realize是一个gtk外部接口函数),而只是被gtk内部的实现所使用。例如,它主要由gtk_widget_map所调用。


5、gtk_widget_map的作用就是显示widget,也即调用XMapWindow操作。因此,gtk_widget_map内部首先会保证widget已经被realized过了。


6、gtk_widget_map一般也只是被gtk内部的实现所使用。它由特定的widget(例如,GtkWindow)的show信号的缺省实现所调用(例如,gtk_window_show),这个信号由gtk_widget_show所触发。


7、gtk_widget_show的作用,标示widget为可以show状态,当top_level的widget接到show信号后,在它的缺省实现中,会调用gtk_widget_map来真正的显示widget。


8、gtk_widget_show_all比较复杂,但是它的作用比较简单,那就是从当前的widget开始,把所有GtkContainer类型的widget(以及child widget)都调用gtk_widget_show。


对于编写gtk应用程序时,显示widget的操作过程如下:
1、从下往上,依次gtk_widget_show每个widget,当top_level的widget被gtk_widget_show时,它会触发gtk_widget_map每个widget,这同样也是从下往上的次序。但是,请注意!gtk_widget_map内部,会隐式地从上往下的顺序调用gtk_widget_realize


2、还有另外一种简单的方法,那就是不依次从下往上gtk_widget_show每个widget,而只是对top_level调用gtk_widget_show_all操作。这个操作,其实质上相当于从下往上,依次gtk_widget_show每个widget。但是它的实现确实比较复杂,在这里,它通过c语言中的callback,完美无缺地实现了类似于C++中的虚函数。
you216 2009-04-23
  • 打赏
  • 举报
回复
Creates the GDK (windowing system) resources associated with a widget. For example, widget->window will be created when a widget is realized. Normally realization happens implicitly; if you show a widget and all its parent containers, then the widget will be realized and mapped automatically.

Realizing a widget requires all the widget's parent widgets to be realized; calling gtk_widget_realize() realizes the widget's parents in addition to widget itself. If a widget is not yet inside a toplevel window when you realize it, bad things will happen.

This function is primarily used in widget implementations, and isn't very useful otherwise. Many times when you think you might need it, a better approach is to connect to a signal that will be called after the widget is realized automatically, such as GtkWidget::expose-event. Or simply g_signal_connect() to the GtkWidget::realize signal.
子晞 2009-04-23
  • 打赏
  • 举报
回复
来源:http://blog.chinaunix.net/u3/90973/showart.php?id=1880382
构件要经过一系列与它们的GdkWindow相关的状态:

如果一个构件相应的GdkWindow被创建出来,称为该构件被显现(realize)。用
gtk_widget_realize()函数显现一个构件,用gtk_widget_unrealize()函数反显现(unrealized)构件。因为X窗口必须有一个父窗口,如果一个构件已经显现,它的父窗口也必然已显现。

如果在构件的GdkWindow上调用了gdk_window_show()函数,称为该构件被映射(map)了。这意味着服务器已经要求在屏幕上显示这个构件的GdkWindow窗口。很明显,GdkWindow窗口必须存在,也就是说,被映射的构件必然已被显现。

如果当一个构件的父构件被映射时,它也被映射到屏幕上,这个构件就是可见的。这意味着已经对该构件调用了gtk_widget_show()函数。通过调用gtk_widget_hide()函数,一个构件可以绘制为不可见的,这或者是取消未决的映射(已经确定了映射的时间,但还未映射),或者反映射该构件(隐藏它的GdkWindow窗口)。因为顶级构件没有父构件,当它们一显示,它们同时就被映射了。

在典型的用户代码中,只需调用gtk_widget_show()函数。这暗含当它的父构件一旦被显现和映射,该构件就被显现和映射。要理解的是: gtk_widget_show()函数并不会立即生效,这一点很重要,它仅仅是确定构件被显示出来的时间。也就是说,不用担心显示构件的顺序(不必一定要先显示子构件,再显示父构件)。但是,这时还不能立即访问这个构件的GdkWindow窗口。有时,又确实需要在映射之前访问构件的GdkWindow 窗口;在这样的情况下,要手工调用gtk_widget_realize()函数来创建这个GdkWindow。如果机会适当, gtk_widget_realize()函数还会显现构件的父构件。使用gtk_widget_realize()函数的情况是不多见的,如果感觉到一定要这么做时,也许是使用了不正确的方法。
laibaohua 2008-08-27
  • 打赏
  • 举报
回复
不要沉了。。。
laibaohua 2008-08-27
  • 打赏
  • 举报
回复
up

23,125

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧