2017-01-09 1 views
0

私はGtkベースのアプリケーションを開発しています.GtkTextBufferをX秒ごとに更新する必要があります。そこに既に存在するテキストを連結します。どうやらそれは成功しますが、アプリケーションが異常終了することもあります。以前は起こっていなかったので、この要素が原因であると想定しています。 2回目/ 3回目の更新があると(それぞれの更新で1つの新しい行が追加される)、時には中止されないことがあります。私は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); 

    [...] 
} 

更新機能が別のスレッドからではなく、「活性化から呼び出されます"テキスト入力ウィジェットのコールバック。あなたの助け

答えて

2

このコードは意味がないため

感謝。より多くのテキストを保持するスペースを持たない文字列に連結しています。これは未定義の動作が起こるのを待っています!投稿された回答は意味がありません。そのようなテキストのコピーを作成することには意味がありません。それはヒープをもう少し使っているだけなので、役立つかもしれません。だから、おそらくあなたは幸運になるでしょう。まだ定義されていない動作がprevious_textに連結されました。

テキストを追加する場合は、テキストの内容全体を再設定する必要はありません。新しいテキストを最後に挿入するには、gtk_text_buffer_insert()を使用してください。最初にgtk_text_buffer_get_iter_at_offset()を使用して、バッファの内容の最後のイテレータを取得します。

UPDATEああ、また、あなたは絶対に複数のスレッドからコールのGTK +はできません。これはスレッドセーフなライブラリではないので、そうしないでください。あなたがしているのは少し不明ですが、それは確かにそれのように聞こえる。

+2

コードがクラッシュする理由の他の部分について話すのを忘れてしまった:GTK +はスレッドセーフではない。 'gdk_threads_add_idle()'を使ってメインのスレッドでGtkTextBufferを調整する必要があります。 – andlabs

+0

@andlabsありがとう、固定。 – unwind

関連する問題