我正在开发一个基于Gtk的应用程序,我需要每X秒更新一个GtkTextBuffer,方法是连接已经存在的文本。很明显它成功了,但有时应用程序会“随机”中止,我认为这是由于这个元素造成的,因为它以前没有发生过。当有第二次/第三次更新(每次更新只添加一个新行)时,它有时会中止,有时根本不会中止。我的TextBuffer更新功能基于简单的聊天应用程序行为,但我不知道我做错了什么。更新功能是:
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);
}
此外,声明并初始化所有gtkwidget的主函数中的相关代码是:
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);
[...]
}
update函数是从另一个线程调用的,而不是从文本输入小部件的“activate”回调调用的。
谢谢你的帮助
最佳答案
那代码没有意义。您正在连接到一个没有空间容纳更多文本的字符串,这是等待发生的未定义行为!你贴出来的答案也没有意义,这样的文本复制是没有意义的。这可能会有帮助,因为它使用堆多一点,所以也许你会变得更幸运。仍然没有定义要连接到previous_text
的行为。
如果要追加更多文本,则无需重新设置整个文本内容。只需使用gtk_text_buffer_insert()
在末尾插入新文本。首先使用gtk_text_buffer_get_iter_at_offset()
获取缓冲区内容末尾的迭代器。
更新哦,而且,您绝对不能从多个线程调用GTK+。它不是线程安全库,所以不要这样做。现在还不清楚你是否会这样做,但听起来确实是这样。