Я думаю, что исправил эту ошибку, но я хочу быть уверен, что сделал это правильно. Также я не уверен, почему это происходит именно так.
Код до исправления:
private Gee.ArrayList<Gtk.Widget> menuButtons;
// Some other code here
public override void remove (Gtk.Widget widget) {
if (widget in menuButtons) {
widget.unparent ();
menuButtons.remove ( widget ); // Look at this method call
if (this.get_visible () && widget.get_visible ()) {
this.queue_resize_no_redraw ();
}
}
}
Код вызывает:
ERROR:arraylist.c:957:gee_array_list_real_get: assertion failed: (index < _size)
./run: line 3: 11054 Aborted (core dumped) ./bin
Код после исправления:
private Gee.ArrayList<Gtk.Widget> menuButtons;
// Some other code here
public override void remove (Gtk.Widget widget) {
if (widget in menuButtons) {
widget.unparent ();
if (this.get_visible () && widget.get_visible ()) {
this.queue_resize_no_redraw ();
menuButtons.remove ( widget ); // Moved method call here
}
}
}
И теперь это работает, я не уверен, но это может быть как-то связано с асинхронным вызовом метода удаления, не так ли?
Любое хорошее объяснение? Это правильное решение проблемы?
@После повторной проверки кода я уверен, что это неправильное решение моей проблемы, потому что menuButtons.remove (widget); никогда не вызывается в моем случае. Виджет остается в списке, и это нежелательное поведение.
МВЦЭ:
MyContainer.vala
public class MyContainer : Gtk.Container {
// ArrayList for storing menu buttons
private Gee.ArrayList<Gtk.Widget> menuButtons;
public MyContainer () {
base.set_has_window (false);
menuButtons = new Gee.ArrayList<Gtk.Widget> ();
}
public override void add (Gtk.Widget widget) {
widget.set_parent (this);
menuButtons.add (widget);
}
public override void remove (Gtk.Widget widget) {
if (widget in menuButtons) {
widget.unparent ();
menuButtons.remove ( widget ); // After removing the widget from the List I get "assertion failed error"
if (this.get_visible () && widget.get_visible ()) {
this.queue_resize_no_redraw ();
}
}
}
public override void forall_internal (bool include_internals, Gtk.Callback callback) {
foreach (var widget in menuButtons) {
callback (widget);
}
}
}
SimpleGtkApplication.vala
public class SimpleGtkApplication : Gtk.Application {
public SimpleGtkApplication () {
Object (application_id: "simple.gtk.application", flags: ApplicationFlags.FLAGS_NONE);
}
protected override void activate () {
Gtk.ApplicationWindow window = new Gtk.ApplicationWindow (this);
window.set_default_size (800, 600);
window.title = "SimpleGtkApplication";
Gtk.Container container = new MyContainer ();
container.add ( new Gtk.Button.with_label ("Button 1") );
container.add ( new Gtk.Button.with_label ("Button 2") );
window.add ( container );
window.show_all ();
}
public static int main (string[] args) {
SimpleGtkApplication app = new SimpleGtkApplication ();
return app.run (args);
}
}
Компилировать с: --pkg=gtk+-3.0 --pkg=gee-0.8
Gtk.Container
? Что вы пытаетесь сделать в первую очередь? Возможно, вы захотите добавить это к вопросу. - person Jens Mühlenhoff   schedule 26.03.2017