如何在C语言中将GList转换为GListModel?
嗨,我来帮你搞定这个问题!在GTK/GLib的开发场景里,把GList转换成GListModel最省心的方式就是用GListStore——它是GLib内置的GListModel实现,专门用来管理一组GObject实例的列表,完美适配你的需求,直接就能传给adw_combo_row_set_model()用。
下面给你一步步拆解具体做法:
第一步:创建GListStore实例
首先要初始化一个GListStore,你需要传入你要存储的对象的GType。比如如果你的GList里存的是字符串,就用GTK_TYPE_STRING_OBJECT;如果是自定义的GObject子类,就传对应的类型。第二步:遍历GList,把元素添加到GListStore
循环遍历你的现有GList,把每个元素逐个添加到GListStore里。这里要注意,如果你的GList里的对象还没有被其他地方引用,记得手动加个引用,避免被提前释放。第三步:把GListStore传给ComboRow
因为GListStore实现了GListModel接口,所以直接转成G_LIST_MODEL类型传进去就行。
给你一个具体的代码示例(假设你的GList里存的是字符串):
// 假设这是你已有的GList,里面存着C字符串 GList *my_string_list = ...; // 创建存储GtkStringObject的GListStore GListStore *list_store = g_list_store_new(GTK_TYPE_STRING_OBJECT); // 遍历GList,把每个字符串包装成GtkStringObject并添加到store for (GList *iter = my_string_list; iter != NULL; iter = iter->next) { const char *current_str = (const char *)iter->data; GtkStringObject *string_obj = gtk_string_object_new(current_str); // 添加到store,store会自动持有对象的引用 g_list_store_append(list_store, string_obj); // 这里可以释放我们刚创建的引用,因为store已经持有了 g_object_unref(string_obj); } // 现在把store传给你的AdwComboRow adw_combo_row_set_model(ADW_COMBO_ROW(your_combo_row), G_LIST_MODEL(list_store)); // 最后记得管理资源:不需要的时候释放store和原GList g_object_unref(list_store); g_list_free(my_string_list); // 如果原GList的内存是你分配的,记得释放
如果你的GList里存的是自定义的GObject子类,代码逻辑类似,只是创建对象的步骤换成你自己的类型就行:
// 假设你的GList里是自定义的MyObject实例 GList *my_obj_list = ...; GListStore *list_store = g_list_store_new(MY_TYPE_OBJECT); for (GList *iter = my_obj_list; iter != NULL; iter = iter->next) { MyObject *obj = MY_OBJECT(iter->data); g_list_store_append(list_store, obj); // 这里如果obj的引用计数只在GList里,记得加引用 g_object_ref(obj); }
另外补充个小提示:如果你需要的是动态同步的视图(也就是原GList的变化要实时反映到GListModel里),那GListStore就不太够了,这时候你得自己实现GListModel接口,还要监听GList的修改事件。不过这种场景比较少见,大部分情况下用GListStore做一次性转换就完全够用了,也是官方推荐的简单方案。
备注:内容来源于stack exchange,提问作者Newbyte

