Я разрабатываю приложение на основе Gtk, где мне нужно обновлять каждые X секунд GtkTextBuffer, объединяя текст, который уже существует. По-видимому, это удается, но иногда «случайным образом» приложение прерывается, и я предполагаю, что это связано с этим элементом, чего раньше не было. Иногда он прерывается, когда есть второе/третье обновление (каждое обновление добавляет только одну новую строку), и иногда оно вообще не прерывается. Я основал функцию обновления TextBuffer для простого поведения приложений чата, но я не знаю, что я делаю неправильно. Функция обновления:Неожиданное прерывание с использованием GtkTextBuffer
void updateTextWindow(char *new_msg){
g_print("Msg rcv: %s\n", new_msg);
GtkTextIter start, end;
GtkTextBuffer *buffer = gtk_text_view_get_buffer (global_text_window);
//global_text_window is a global gtkwidget where TextBuffer is embedded
gchar *previous_text;
gtk_text_buffer_get_bounds (buffer, &start, &end);
previous_text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
strcat(previous_text, "\n");
strcat(previous_text, new_msg);
gtk_text_buffer_set_text(buffer, previous_text, -1);
g_free(previous_text);
}
Кроме того соответствующий код в основной функции, где все GtkWidgets объявлены и initializated является:
void create_ui (CustomData *data) {
[...]
GtkWidget *secondary_box; /* for text entry & buffer */
GtkScrolledWindow *scrolling_box;
GtkWidget *text_window;
GtkTextBuffer *buffer;
GtkWidget *text_entry;
secondary_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 1);
gtk_widget_set_size_request(secondary_box, 600, -1);
scrolling_box = gtk_scrolled_window_new(NULL, NULL);
gtk_scrolled_window_set_policy(scrolling_box, GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
text_entry = gtk_entry_new();
global_text_entry = text_entry;
gtk_entry_set_max_length(text_entry, 25);
text_window = gtk_text_view_new();
buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_window));
gtk_text_buffer_set_text(buffer, "\n", -1);
gtk_text_view_set_editable(text_window, FALSE);
global_text_window = text_window;
gtk_scrolled_window_add_with_viewport(scrolling_box, text_window);
gtk_box_pack_end(GTK_CONTAINER(secondary_box), text_entry, FALSE, FALSE, 0);
g_signal_connect(G_OBJECT(text_entry), "activate", G_CALLBACK(text_entry_cb), &data);
gtk_box_pack_end(GTK_CONTAINER(secondary_box), scrolling_box, TRUE, TRUE, 0);
[...]
}
функция обновления вызывается из другого потока, а не от «Activate "обратный вызов для виджета ввода текста.
Спасибо за вашу помощь
Вы забыли поговорить о другой части причины сбоя кода: GTK + не является потокобезопасным; все настройки GtkTextBuffer должны быть сделаны в основном потоке, используя 'gdk_threads_add_idle()' для планирования действий основного потока. – andlabs
@andlabs Спасибо, исправлено. – unwind