Ich entwickle eine Gtk-basierte Anwendung, wo ich alle X Sekunden ein GtkTextBuffer aktualisieren muss, indem Sie den bereits vorhandenen Text verketten. Scheinbar gelingt es aber manchmal "zufällig" bricht die Anwendung ab und ich nehme an, dass es an diesem Element liegt, da es vorher nicht passiert ist. Es wird manchmal abgebrochen, wenn ein zweites/drittes Update durchgeführt wird (jedes Update fügt nur eine neue Zeile hinzu) und manchmal bricht es überhaupt nicht ab. Ich habe die TextBuffer-Update-Funktion auf einfache Chat-Anwendungen Verhalten, aber ich weiß nicht, was ich falsch mache. Die Update-Funktion ist:Unerwarteter Abbruch mit 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);
}
Darüber hinaus ist der zugehörige Code in der Hauptfunktion, in der alle GtkWidgets deklarieren und initializated ist:
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);
[...]
}
Die Update-Funktion von einem anderen Thread aufgerufen wird, nicht von der „activate "Rückruf für das Texteingabe-Widget.
Vielen Dank für Ihre Hilfe
Sie haben vergessen, über den anderen Teil des Grundes zu sprechen, warum der Code abstürzt: GTK + ist nicht Thread-sicher; Alle Anpassungen am GtkTextBuffer müssen im Hauptthread vorgenommen werden, wobei 'gdk_threads_add_idle() 'zum Planen von Haupt-Thread-Aktionen verwendet wird. – andlabs
@andlabs Danke, behoben. – unwind