使用GtkBuilder要注意的问题

在使用GtkBuilder创建系统托盘时遇到错误,弹出式菜单无法正常显示。原因是GtkBuilder在构造完成后会持有对象引用,当其被回收时,非顶级窗口对象也会被销毁。为避免此问题,需要正确管理对象生命周期,如使用g_object_ref保持GtkStatusIcon和GtkMenu的存活,并在适当时候释放,防止内存泄漏。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

最近想用GTK实现一个系统托盘,我使用的开发工具是Anjuta+Glade,很自然就会用到GtkBuilder。结果问题来了,弹出式菜单显示不了, 出现了如下的错误:

 

(monitor:3810): Gtk-CRITICAL **: gtk_status_icon_set_visible: assertion `GTK_IS_STATUS_ICON (status_icon)' failed


(monitor:3810): Gtk-CRITICAL **: gtk_menu_popup: assertion `GTK_IS_MENU (menu)' failed

看来,不仅仅弹出式菜单有问题,status icon也是有问题的。
我的代码很简单,会有什么问题呢?

 

 
查过了资料才发现,原来是GtkBuilder所引起的。

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.

The functions gtk_builder_get_object() and gtk_builder_get_objects() can be used to access the widgets in the interface by the names assigned to them inside the UI description. Toplevel windows returned by these functions will stay around until the user explicitly destroys them with gtk_widget_destroy(). Other widgets will either be part of a larger hierarchy constructed by the builder (in which case you should not have to worry about their lifecycle), or without a parent, in which case they have to be added to some container to make use of them. Non-widget objects need to be reffed with g_object_ref() to keep them beyond the lifespan of the builder.


原来GtkStatusIcon和GtkMenu一个是non-widget,一个是widget,但不是toplevel,一旦GtkBuilder的对象被回收,它们也会被释放.所以在使用完GtkBuilder后,我们不能让系统将它回收,不然,GtkStatusIcon和GtkMenu的对象也会被释放的。因此,将g_object_unref改成g_object_ref,让GtkBuilder的reference count不为0,等到释放GtkStatusIcon和GtkMenu对象后,系统就会回收GtkBuilder对象的。在这里,也不能不加g_object_ref,不然,就很容易造成内存泄漏。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值