Проблема с GtkTextBuffer, запутанная ошибка времени выполнения. Нужна помощь?

Я использую этот код:

class editbook
{
  GtkWidget* _nbook;
  std::vector<GtkWidget*> _srcset; //and so on...

...........................................................................................

void editbook::add_page()
{
    GtkWidget* tmp = gtk_source_view_new();
    _srcset.push_back(tmp);
    gtk_notebook_append_page(GTK_NOTEBOOK(_nbook),tmp,gtk_label_new("untitled"));
}

...........................................................................................

void editbook::set_text(const std::string& text)
{
    int index = gtk_notebook_get_current_page(GTK_NOTEBOOK(_nbook));
    GtkTextBuffer* tbuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(_srcset[index]));
    gtk_text_buffer_set_text(GTK_TEXT_BUFFER(tbuffer),text.c_str(),-1);
}

Компилируется нормально. Но дает эту странную ошибку времени выполнения:

Ошибка сегментации: возврат 139

Я проследил проблему до: gtk_text_view_get_buffer(GTK_TEXT_VIEW(_srcset[index]));

ПРИМЕЧАНИЕ. Я использую GtkSourceView вместо GtkTextView, но это может не быть проблемой, потому что я получаю ту же ошибку, когда пытаюсь использовать GtkTextView.

ПРИМЕЧАНИЕ. Я использую Gtk 2x.

ПРИМЕЧАНИЕ. Я не уверен, следует ли помечать этот вопрос как C или C++. быть Gtk+ — это C-lib. Но я использую С++. Так что я просто пометить обоих на данный момент.


person ApprenticeHacker    schedule 22.09.2011    source источник
comment
Не могли бы вы опубликовать, что такое массив _srcset? Кстати, почему бы вам не использовать GtkMM ( gtkmm.org/en ), который является оболочкой C++ над Gtk если вы хотите написать свой код на C++?   -  person another.anon.coward    schedule 22.09.2011
comment
@anoner.anon.coward std::vector<GtkWidget*> _srcset . Заполнен GtkSourceViews (gtk_source_view_new()); Что касается ГТКММ. Честно говоря, я не использую его, потому что я идиот... И потому что он по какой-то причине не компилируется в Ubuntu (glibmmconfig.h не найден)   -  person ApprenticeHacker    schedule 22.09.2011
comment
Вы показываете недостаточно информации. Расскажите нам, где вы определяете _srcset и почему _srcset[index] должен быть действительной ссылкой во время выполнения.   -  person sehe    schedule 22.09.2011
comment
@sehe Теперь у тебя достаточно информации?   -  person ApprenticeHacker    schedule 22.09.2011
comment
Хммм ... Вы проверили, возвращен ли буфер для NULL и являются ли они допустимыми объектами? Я имею в виду, каков результат для GTK_IS_TEXT_VIEW(_srcset[index]) и GTK_IS_TEXT_BUFFER(tbuffer)? Кроме того, я бы посоветовал вам использовать vector::at вместо operator[], чтобы быть уверенным, что вы не выходите за пределы допустимого диапазона.   -  person another.anon.coward    schedule 22.09.2011


Ответы (1)


Проблема в вашем коде может заключаться в том, что дочерний виджет, добавленный с GtkNotebook по gtk_notebook_append_page, не видим, попробуйте отобразить дочерний виджет с помощью вызова gtk_widget_show. Что-то в этих строках:

void editbook::add_page()
{
    GtkWidget* tmp = gtk_source_view_new();
    _srcset.push_back(tmp);
    gtk_widget_show(tmp); //Show the child widget to make it visible
    gtk_notebook_append_page(GTK_NOTEBOOK(_nbook),tmp,gtk_label_new("untitled"));
}

Когда вы используете gtk_notebook_get_current_page, если ни один из дочерних виджетов не виден, он возвращает -1, что, я думаю, может происходить в вашем случае, и поскольку index является -1, когда вы используете operator[], который не проверяет границы, программа аварийно завершает работу. Я настоятельно рекомендую вам использовать vector::at вместо operator[], чтобы во время выполнения вы получали исключение std::out_of_range, указывающее на проблему. Вы можете использовать:

void editbook::set_text(const std::string& text)
{
    int index = gtk_notebook_get_current_page(GTK_NOTEBOOK(_nbook));
    GtkTextBuffer* tbuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(_srcset.at(index)));
    gtk_text_buffer_set_text(GTK_TEXT_BUFFER(tbuffer),text.c_str(),-1);
}

Надеюсь это поможет!

person another.anon.coward    schedule 23.09.2011