Gtk-warning:多次写入同一文本视图时文本缓冲区迭代器无效

时间:2014-09-26 04:55:45

标签: c gtk

以下函数每秒调用一次,并尝试编写total_successful_connects。 它有时工作,但我得到上述错误和程序崩溃。

gtk_text_buffer_set_text()将删除先前的缓冲区内容。它不验证迭代器吗?

如果没有,我该怎么做才能验证迭代器?

void display_status()
{
    char output_str[100];

    sprintf(output_str, "%u", stats->total_successful_connects);
    gtk_text_buffer_set_text(
        config->text_buffer,
        output_str, strlen(output_str));

}

我在启动期间通过调用gtk_text_view_get_buffer(my_text_view)初始化了config-> textbuffer

我使用的是gtk + 2

详细错误:

(gedit:7793): Gtk-WARNING **: Invalid text buffer iterator: either the iterator is uninitialized, or the characters/pixbufs/widgets in the buffer have been modified since the iterator was created.
You must use marks, character numbers, or line numbers to preserve a position across buffer modifications.
You can apply tags and insert marks without invalidating your iterators,
but any mutation that affects 'indexable' buffer contents (contents that can be referred to by character offset)
will invalidate all outstanding iterators

2 个答案:

答案 0 :(得分:1)

您应该使用gdk_threads_add_idle()来安排主线程中对gtk_text_buffer_set_text()的调用。像这样:

struct DispatchData {
    GtkTextBuffer *buffer;
    char *output_str;
};

static gboolean display_status_textbuffer(struct DispatchData *data)
{
    gtk_text_buffer_set_text(data->buffer, data->output_str, strlen(data->output_str));
    g_free(data);
    return G_SOURCE_REMOVE;
}

void display_status()
{
    struct DispatchData *data = g_new0(struct DispatchData, 1);
    data->output_str = g_strdup_printf("%u", stats->total_successful_connects);
    data->buffer = config->buffer;
    gdk_threads_add_idle(display_status_textbuffer, data);
}

(假设您在display_status()中执行的非GUI工作比上面显示的更多;否则,只使用gdk_threads_add_timeout()启动的每秒一个函数是有意义的

答案 1 :(得分:0)

您无法在线程内更新GUI。 您可以使用“g_timeout_add”为GUI窗口分配超时,并让它调用更新GUI的功能(从主程序)。 您的线程可以更新值,但超时调用的函数可以更新文本缓冲区。

cog_timeout_add(1000, (GSourceFunc) time_handler, (gpointer) window) ;

--->将此位置放在gtk_widget_show(窗口)上方 --->然后放置命令强制它不要等待第一秒

time_handler(window) ;

然后在你的主程序中编写它调用的函数。

static gboolean time_handler(GtkWidget *widget) {
    gtk_text_buffer_set_text (textbuffer, stufftosay, -1) ;
    return TRUE ;
}