Hello all: Firstly, Thanks Richard for his valuable infomation and thanks all who reply me. I still follow the thread "A problem about programming with Gtk+(gtk-list Digest, Vol 56, Issue 22)". Maybe I unintentionally changed the subject in my code:) I followed the step of Richard's guide, everything run well, but I can not exit from the callback of g_idle_add correctly. Why? Following is the code: //gcc -o tbug t_bug3.c `pkg-config --cflags --libs gtk+-2.0`-lgthread-2.0 -g // #include <unistd.h> #include <stdlib.h> #include <gtk/gtk.h> #include <pthread.h> #include <glib.h> GtkWidget *win; static GtkWidget *xpm_label_box( gchar *xpm_filename, gchar *label_text ) { GtkWidget *box; GtkWidget *label; GtkWidget *image; box = gtk_hbox_new (FALSE, 0); gtk_container_set_border_width (GTK_CONTAINER (box), 2); image = gtk_image_new_from_file (xpm_filename); label = gtk_label_new (label_text); gtk_box_pack_start (GTK_BOX (box), image, FALSE, FALSE, 3); gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 3); gtk_widget_show (image); gtk_widget_show (label); return box; } static gboolean Result (gpointer data) { gint param = (gint)data; GtkWidget* pDialog = gtk_message_dialog_new(GTK_WINDOW(win), GTK_DIALOG_MODAL, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, "The thread result: %d ", param); gtk_dialog_run(GTK_DIALOG(pDialog)); gtk_widget_destroy(pDialog); return FALSE; } static gpointer cursor_change(gpointer data) { //1) do your work GtkWidget *window = (GtkWidget *) data; win = window; int i,j; for(i=0;i<100;i++) { g_print ("Hello again - %s was pressed %d\n", (char *) data, i); } //2) call g_idle_add to render the result to user g_idle_add( Result, (gpointer)i); return NULL; } static void callback( GtkWidget *widget, gpointer data ) { //1) modify the cursor as necessary GtkWidget *window = (GtkWidget *) data; GdkCursor *new_cursor; new_cursor=gdk_cursor_new(GDK_WATCH); g_print ("I make it!"); gdk_window_set_cursor(window->window, new_cursor); gdk_cursor_destroy(new_cursor); //2) create the thread to do the background work g_thread_create ( cursor_change, data, TRUE, NULL); //3) quit return; } int main( int argc, char *argv[] ) { GtkWidget *window; GtkWidget *button; GtkWidget *box; gtk_init (&argc, &argv); if (!g_thread_supported ()) { g_thread_init(NULL); gdk_threads_init(); } window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_title (GTK_WINDOW (window), "Pixmap'd Buttons!"); g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (gtk_main_quit), NULL); g_signal_connect (G_OBJECT (window), "delete_event", G_CALLBACK (gtk_main_quit), NULL); gtk_container_set_border_width (GTK_CONTAINER (window), 10); button = gtk_button_new (); g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (callback), (gpointer) window); box = xpm_label_box ("info.xpm", "cool button"); gtk_widget_show (box); gtk_container_add (GTK_CONTAINER (button), box); gtk_widget_show (button); gtk_container_add (GTK_CONTAINER (window), button); gtk_widget_show (window); gtk_main (); return 0; } ----------------------------- Message: 4 Date: Sat, 20 Dec 2008 12:16:34 +0100 (CET) From: "Richard Boaz" <riboaz@xxxxxxxxx> Subject: A problem about programming with Gtk+ To: gtk-list@xxxxxxxxx Message-ID: <8500.83.82.225.199.1229771794.squirrel@xxxxxxxxxxxxxxxxx> Content-Type: text/plain;charset=iso-8859-1 what exactly are you trying to do? cause your program's not gonna do much as it is, and it's not obvious to me what exactly you're trying to achieve here. if it's related to modifying the cursor as a result of user interaction, you should try another model. that is, set up a different thread to do the background work, not change the cursor. and you instantiate this thread from within the callback, not as part of your main routine. so, the sequence of events might be: in your callback: 1) modify the cursor as necessary 2) create a thread to do the background work 3) quit in your thread: 1) do your work 2) call g_idle_add() invoking a function that understands you are returning from your background thread, i.e., render the results back to the user basic guidelines to follow: 1) have your callback do as little work as possible. 2) do any work requiring time in a separate thread, returning to the mainloop via g_idle_add() following this model, you will gain the following: 1) user interface will always be responsive since mainloop() will remain free to process events 2) cursor will change in a timely fashion 3) multiple cpu's will be utilized to their best advantage if this isn't what you want, then perhaps you could restate your goals? cheers, richard -- ======================================================= Sincerely, Alfred Young R&D, Application Architectures www.foxitsoftware.com _______________________________________________ gtk-list mailing list gtk-list@xxxxxxxxx http://mail.gnome.org/mailman/listinfo/gtk-list