GTK4中能否用标准GObject类型替代自定义对象存储指针?
解决方案
方法1:用极简自定义GObject封装指针
你不用写复杂的自定义GObject,只需要几行代码就能实现一个仅用来存储指针的轻量级GObject:
#include <glib-object.h> G_DECLARE_FINAL_TYPE(SimplePointerHolder, simple_pointer_holder, SIMPLE, POINTER_HOLDER, GObject) struct _SimplePointerHolder { GObject parent_instance; gpointer data; }; G_DEFINE_TYPE(SimplePointerHolder, simple_pointer_holder, G_TYPE_OBJECT) static void simple_pointer_holder_init(SimplePointerHolder *self) {} static void simple_pointer_holder_class_init(SimplePointerHolderClass *klass) {} SimplePointerHolder *simple_pointer_holder_new(gpointer data) { SimplePointerHolder *holder = g_object_new(SIMPLE_TYPE_POINTER_HOLDER, NULL); holder->data = data; return holder; } gpointer simple_pointer_holder_get_data(SimplePointerHolder *holder) { return holder->data; }
使用时直接把普通指针传入,再传给gtk_builder_set_current_object:
gpointer my_data = ...; // 你的普通指针 SimplePointerHolder *holder = simple_pointer_holder_new(my_data); gtk_builder_set_current_object(builder, G_OBJECT(holder));
回调里取出数据:
void some_callback(GtkWidget *widget, gpointer user_data) { SimplePointerHolder *holder = SIMPLE_POINTER_HOLDER(user_data); gpointer my_data = simple_pointer_holder_get_data(holder); // 使用my_data }
方法2:利用GObject的set_data/get_data附加数据到Builder本身
如果你不想额外创建GObject,可以把普通指针直接附加到GtkBuilder实例上,再在回调里从Builder获取:
// 设置数据 gpointer my_data = ...; g_object_set_data(G_OBJECT(builder), "my-custom-data", my_data); // 回调里获取(需确保能访问到builder实例,比如通过全局变量或从widget祖先查找) void some_callback(GtkWidget *widget, gpointer user_data) { gpointer my_data = g_object_get_data(G_OBJECT(builder), "my-custom-data"); // 使用my_data }
这种方法不需要额外创建GObject,但要保证回调里能拿到GtkBuilder的引用。
为什么G_TYPE_POINTER不行?
G_TYPE_POINTER属于GBoxed类型,并非GObject派生类型,而gtk_builder_set_current_object明确要求传入GObject指针。强制转换后,GTK会尝试对其调用GObject的核心方法(如引用计数操作),但GBoxed类型没有对应的结构,必然导致运行时崩溃。
内容的提问来源于stack exchange,提问作者Michael K.
相关产品推荐
相关产品推荐

