Реализация ListModel с Gee.ArrayList - PullRequest
0 голосов
/ 06 февраля 2019

Так что я подумал, что я буду умным одним из более общих и простых в использовании классов, а именно Gee.ArrayList для данных для ListBox.Оказывается, что 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);
    }

}

This,однако дает мне странное сообщение компиляции:

/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

Есть хороший способ решить эту проблему, или я пытался что-то, что было неправильно с самого начала?

1 Ответ

0 голосов
/ 07 февраля 2019

Важно помнить, что Vala на самом деле компилируется в C, который затем подается в GCC для создания исполняемого файла, а предупреждение вашего компилятора на самом деле составляется из gcc not 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

Итак, у вас есть 2 проблемы

  1. Вашневерный идентификатор приложения.Взгляните на HowDoI / ChooseApplicationID , чтобы помочь решить, что использовать вместо «TestApp», как правило, что-то вроде com.githost.me.App
  2. На самом деле вы не установили метод для связывания модели споэтому Gtk отклоняет его, убедитесь, что вы действительно передали ему функцию

Однако ни один из них не говорит нам, почему вы получаете SEGV

Ответ заключается в том, что ваша GListModel содержит элементы типаint, тогда как GtkListBox ожидает коллекцию Object

...