编程笔记:GtkBuilder和popup menu

今天又奋战gtk的文档,看着别人写的旧版example代码,用GtkBuilder的方法重写,实现了一个自己想要的TreeView List。最后想在TreeView中加入一个右键菜单,却想不到小小的popup menu就给我设了两大难关。

首先找来找去没有见到有right-click的signal,Google了一下,从Maillist里面的解答找到头绪,由GtkWidget的button_press_event来实现。GTK+ Reference Manual里面一点都没提到这个信号,原来这个button指鼠标的button,键盘的键叫做key……

http://mail.gnome.org/archives/gtk-list/2002-August/msg00119.html

button_press_event emits when any mouse button pressed, when handling with this signal, use a callback prototype in this way:

gboolean callback (GtkWidget *widget,
GdkEventButton *event,
gpointer data);

and you can determine which button was press with event->button (values 1,2,3…3 stands for the right button, 1 for left and 2 for middle), and if you want give this signal back to the widget, just return FALSE.

另外一个问题是popup menu, 在glade3里面添加了一个popup menu, 照搬老方法,初始化程序的时候

tree->menu = GTK_WIDGET ( gtk_builder_get_object (builder, “menu1”) );

弹出窗口:

gtk_menu_popup (GTK_MENU(user_data->menu), NULL, NULL, NULL, NULL, event->button, event->time);

郁闷的事情来了,程序运行的时候提示:

(tree:28254): GLib-GObject-WARNING **: invalid unclassed pointer in cast to `GtkMenu’

(tree:28254): Gtk-CRITICAL **: gtk_menu_popup: assertion `GTK_IS_MENU (menu)’ failed

在Reference里面看了半天,注意到GtkBuilder Description的一段话:

A GtkBuilder holds a reference to all objects that it has constructed and drops these references when it is finalized. This finalization can cause the destruction of non-widget objects or widgets which are not contained in a toplevel window. For toplevel windows constructed by a builder, it is the responsibility of the user to call gtk_widget_destroy() to get rid of them and all the widgets they contain.

在Glade3里面看到,popup menu不属于toplevel的window,看来小menu在g_object_unref (G_OBJECT (builder));的时候被收回去了……可是怎么解决呢?总不能不收了builder吧,builder占的内存可不小的,很容易造成内存泄漏……

It’s obvious that the menu allocation was released after initialing the application, I have to solve this problem.

In the Reference Manual, I found a function.

g_object_ref ()

gpointer g_object_ref (gpointer object);

Increases the reference count of object.

The reference count really mean something, worth to read about it carefully. I just add one more statement after getting the menu widget:

这个reference count大有来头。在gtk_builder_get_object (builder, “menu1”)后,加了一句:

g_object_ref ((gpointer)tree->menu);

Yes,the whole world goes the right way now!!!!

文章分类 GTK +, Programming

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*