GTK and threads
- From: Bernhard Jung <bernhard bernhardjung de>
- To: gtk-list gnome org
- Subject: GTK and threads
- Date: Tue, 29 Jul 2008 16:00:01 +0200
Hi,
I'm currently having a problem in a application where I try to update a
GtkListStore from a thread. When calling gtk_list_store_set I often get error
messages that repeat
Gtk-CRITICAL **: gtk_tree_model_sort_get_value:
assertion `VALID_ITER (iter, tree_model_sort)' failed
GLib-GObject-CRITICAL **: g_object_set_property:
assertion `G_IS_VALUE (value)' failed
GLib-GObject-CRITICAL **: g_value_unset:
assertion `G_IS_VALUE (value)' failed
and end with
Gtk-CRITICAL **: file /build/buildd/gtk+2.0-2.12.9/gtk/gtktreeview.c:
line 6154 (do_validate_rows):
assertion `gtk_tree_model_iter_next (tree_view->priv->model, &iter)'
failed.
There is a disparity between the internal view of the GtkTreeView,
and the GtkTreeModel. This generally means that the model has changed
without letting the view know. Any display from now on is likely to
be incorrect.
In worst case it all ends with a segmentation fault.
Below you'll find a sample application that allows to update a list store via
a thread or directly. Given enough columns and rows in the model the updating
through a thread always results in a segmentation fault but the direct update
seems to work without problems. At least on my system.
Is this behavior normal to GTK+? I know in Java/Swing and .NET/Windows Forms
manipulation of GUI widgets has to be done in a special thread. Is there a
similar concept in GTK+? Or maybe something is wrong with my code?
I'm using GTK+ 2.12.9 on Ubuntu 8.04.
Thanks in advance
Bernhard
#include <gtk/gtk.h>
enum {
COLUMN_1_INT = 0,
COLUMN_2_STRING,
COLUMN_3_STRING,
COLUMN_4_STRING,
COLUMN_5_STRING,
COLUMN_6_STRING,
COLUMN_7_STRING,
COLUMN_8_STRING,
COLUMN_9_STRING,
COLUMN_10_STRING,
NO_OF_COLUMNS
};
static int counter = 0;
static GtkListStore *store;
static gpointer update_store ( gpointer user_data )
{
int i;
GtkTreeIter iter;
gtk_list_store_clear ( store );
++counter;
for ( i = 0; i < 3000 ; ++i )
{
gtk_list_store_append ( store, &iter );
gtk_list_store_set ( store, &iter,
COLUMN_1_INT, counter,
COLUMN_2_STRING, "column 2",
COLUMN_3_STRING, "column 3",
COLUMN_4_STRING, "column 4",
COLUMN_5_STRING, "column 5",
COLUMN_6_STRING, "column 6",
COLUMN_7_STRING, "column 7",
COLUMN_8_STRING, "column 8",
COLUMN_9_STRING, "column 9",
COLUMN_10_STRING, "column 10",
-1 );
}
return NULL;
}
static void tree_view_setup_column ( GtkTreeView *tree_view, int columnIndex )
{
GtkTreeViewColumn *column = gtk_tree_view_column_new ();
GtkCellRenderer *renderer = gtk_cell_renderer_text_new ();
gtk_tree_view_column_pack_start ( column, renderer, FALSE );
gtk_tree_view_column_add_attribute ( column, renderer, "text",
columnIndex);
gtk_tree_view_append_column ( tree_view, column );
}
gboolean on_direct_clicked ( GtkToolButton *button, gpointer user_data )
{
update_store ( NULL );
return FALSE;
}
gboolean on_thread_clicked ( GtkToolButton *button, gpointer user_data )
{
g_thread_create ( update_store, NULL, FALSE, NULL );
return FALSE;
}
int main (int argc, char *argv[])
{
int i;
GtkWidget *window;
GtkScrolledWindow *scrolled_w;
GtkTreeView *tree_view;
GtkBox *hbox;
GtkToolbar *toolbar;
GtkToolItem *button;
gtk_init (&argc, &argv);
g_thread_init ( NULL );
hbox = GTK_BOX( gtk_vbox_new ( FALSE, 5 ) );
toolbar = GTK_TOOLBAR( gtk_toolbar_new() );
button = gtk_tool_button_new ( NULL, "direct" );
g_signal_connect( button, "clicked", G_CALLBACK(on_direct_clicked),NULL );
gtk_toolbar_insert ( toolbar, button, -1 );
button = gtk_tool_button_new ( NULL, "thread" );
g_signal_connect( button, "clicked", G_CALLBACK(on_thread_clicked),NULL );
gtk_toolbar_insert ( toolbar, button, -1 );
gtk_box_pack_start ( hbox, GTK_WIDGET( toolbar ), FALSE, TRUE, 0 );
tree_view = GTK_TREE_VIEW( gtk_tree_view_new () );
for ( i = 0 ; i < NO_OF_COLUMNS ; ++i )
tree_view_setup_column ( tree_view, i );
store = gtk_list_store_new ( NO_OF_COLUMNS,
G_TYPE_INT, // COLUMN_1_INT
G_TYPE_STRING, // COLUMN_2_STRING
G_TYPE_STRING, // COLUMN_3_STRING
G_TYPE_STRING, // COLUMN_4_STRING
G_TYPE_STRING, // COLUMN_5_STRING
G_TYPE_STRING, // COLUMN_6_STRING
G_TYPE_STRING, // COLUMN_7_STRING
G_TYPE_STRING, // COLUMN_8_STRING
G_TYPE_STRING, // COLUMN_9_STRING
G_TYPE_STRING // COLUMN_10_STRING
);
update_store ( NULL );
gtk_tree_view_set_model ( tree_view, GTK_TREE_MODEL( store ) );
scrolled_w = GTK_SCROLLED_WINDOW( gtk_scrolled_window_new( NULL, NULL ) );
gtk_scrolled_window_add_with_viewport( scrolled_w, GTK_WIDGET(tree_view));
gtk_box_pack_start ( hbox, GTK_WIDGET( scrolled_w ), TRUE, TRUE, 0 );
window = gtk_window_new ( GTK_WINDOW_TOPLEVEL );
g_signal_connect ( window, "destroy", gtk_main_quit, NULL );
gtk_container_add ( GTK_CONTAINER( window ), GTK_WIDGET( hbox ) );
gtk_window_set_default_size ( GTK_WINDOW( window ), 640, 480 );
gtk_widget_show_all ( window );
gtk_main ();
return 0;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]