Implementing ListModel with Gee.ArrayList



所以我认为我应该是一个更通用、更易于使用的类,即用于ListBox数据的Gee.ArrayList。事实证明,ListBox将采用ListModel,我认为,由于我使用的是ArrayList,我还不如创建一个既是Gee.ArrayList又是ListModel的类:

public class ObservableArrayList<T> : ListModel, Gee.ArrayList<T>{
//Implement ListModel
public Object? get_item(uint position){
if((int)position > size){
return null;
}
return (Object?) this.get((int)position);
}
public Type get_item_type(){
return element_type;
}
public uint get_n_items(){
return (uint)size;
}
public new Object? get_object(uint position){
if((int)position > size){
return null;
}
return (Object) this.get((int)position);
}
}

然而,这给了我一个奇怪的编译信息:

/home/rasmus/Projects/Vala/Test/ObservableList.vala.c: In function ‘observable_array_list_g_list_model_interface_init’:
/home/rasmus/Projects/Vala/Test/ObservableList.vala.c:189:18: warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
iface->get_item = (GObject* (*) (GListModel*, guint)) observable_array_list_real_get_item;

当编译成功时,该类作为ListModel:非常不可用

using Gtk;
public class TestApp : Gtk.Application{
public TestApp () {
Object (
application_id: "TestApp",
flags: ApplicationFlags.FLAGS_NONE
);
}
protected override void activate(){
var main_window = new Gtk.ApplicationWindow (this);
main_window.default_height = 400;
main_window.default_width = 600;
main_window.title = "test";
ListModel t = new ObservableArrayList<int>();
var list_box = new Gtk.ListBox();
list_box.bind_model(t, null);
main_window.add(list_box);
main_window.show_all ();
}
public static int main (string[] args) {
Gtk.init (ref args);
var app = new TestApp ();
return app.run(args);
}
}   

当尝试运行编译程序时,其输出为:

segmentationfault

有没有一个好的方法来解决这个问题,或者我从一开始就在尝试错误的东西?

需要记住的一件重要事情是,Vala实际上编译到C,然后将C输入GCC以构建可执行文件,编译器警告实际上是从gcc而不是valac编译

在我的机器上,消息的格式略有不同

warning: assignment to ‘void * (*)(GListModel *, guint)’ {aka ‘void * (*)(struct _GListModel *, unsigned int)’} from incompatible pointer type ‘GObject * (*)(GListModel *, guint)’ {aka ‘struct _GObject * (*)(struct _GListModel *, unsigned int)’}

可以简化为

assignment to ‘void * (*)(GListModel *, guint)’ from incompatible type ‘GObject * (*)(GListModel *, guint)’

这基本上是说GLib希望get_item返回void *而不是GObject,这是绑定中的一个错误,因此可以忽略

运行附带运行时警告

(list:4511): GLib-GIO-CRITICAL **: 21:44:24.003: g_application_set_application_id: assertion 'application_id == NULL || g_application_id_is_valid (application_id)' failed
(list:4511): Gtk-CRITICAL **: 21:44:24.008: gtk_list_box_bind_model: assertion 'model == NULL || create_widget_func != NULL' failed

所以你有两个问题

  1. 您的应用程序id错误。查看HowDoI/ChooseApplicationID以帮助决定使用什么而不是"TestApp",通常类似于com.githost.me.App
  2. 您实际上还没有设置绑定模型的方法,所以Gtk拒绝了它,请确保您确实在那里传递了一个函数

然而,这两个都没有告诉我们为什么你会得到SEGV

答案在于,您的GListModel包含int类型的元素,而GtkListBox期望Object的集合

最新更新