Greetings gtk-app-devel-list. I'm a newbie GTK+ developer and I have encountered with a problem.
I tried to create a DC Motor Transient process calculation as a practice programm for learning. I've wanted to have a feedback of the calculation process on a progress bar. Documentation say that "the threading support has been deprecated in GTK+ 3.6. Instead of calling GTK+ directly from multiple threads, it is recommended to use g_idle_add(), g_main_context_invoke() and similar functions to make these calls from the main thread instead". I have no idea how g_main_context_invoke() could be usefull for that and g_idle_add() is totally wrong: because if something heavy in the function happens, then the GUI hangs anyway. I don't adequate way to transfer status report from a thread, that blocks a lot, for example very laggy socket connections. Here's a minimal programm. Somehow GTK+ calls from thread are working. How sinfull is that? #include <stdlib.h> #include <gtk/gtk.h> struct CallbackObject { GtkWidget *win; GtkWidget *button; GtkWidget *progress; }; gpointer thread_func( struct CallbackObject *callobj ); static void startstop_thread (GtkWidget *wid, struct CallbackObject *callobj); GThread *pthread = NULL; gboolean thread_run = FALSE; const gchar *label_start = "Start thread"; const gchar *label_stop = "Stop thread"; gpointer thread_func( struct CallbackObject *callobj ) { gdouble x = 0.0; while (x < 1.0 && thread_run == TRUE) { usleep (20*1000); x += 1.0 / 50; gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (callobj->progress), x); } thread_run = FALSE; pthread = NULL; gtk_button_set_label (GTK_BUTTON (callobj->button), label_start); return NULL; } static void startstop_thread (GtkWidget *wid, struct CallbackObject *callobj) { gpointer user_data = callobj; if (thread_run == FALSE) { thread_run = TRUE; pthread = g_thread_new ("thread", (GThreadFunc) thread_func, user_data); gtk_button_set_label (GTK_BUTTON (callobj->button), label_stop); } else { thread_run = FALSE; g_thread_join (pthread); pthread = NULL; gtk_button_set_label (GTK_BUTTON (callobj->button), label_start); } } int main (int argc, char *argv[]) { GtkWidget *button = NULL; GtkWidget *vbox = NULL; struct CallbackObject *callobj = NULL; /* Initialize GTK+ */ g_log_set_handler ("Gtk", G_LOG_LEVEL_WARNING, (GLogFunc) gtk_false, NULL); gtk_init (&argc, &argv); g_log_set_handler ("Gtk", G_LOG_LEVEL_WARNING, g_log_default_handler, NULL); callobj = g_malloc (sizeof(struct CallbackObject)); /* Create the main window */ callobj->win = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_container_set_border_width (GTK_CONTAINER (callobj->win), 8); gtk_window_set_title (GTK_WINDOW (callobj->win), "GTK+-3.10.7-1 Threads"); gtk_window_set_position (GTK_WINDOW (callobj->win), GTK_WIN_POS_CENTER); gtk_widget_realize (callobj->win); g_signal_connect (callobj->win, "destroy", gtk_main_quit, NULL); /* Create a vertical box with buttons */ vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 8); gtk_container_add (GTK_CONTAINER (callobj->win), vbox); callobj->progress = gtk_progress_bar_new (); gtk_progress_bar_set_show_text (GTK_PROGRESS_BAR (callobj->progress), TRUE); gtk_box_pack_start (GTK_BOX (vbox), callobj->progress, TRUE, TRUE, 0); callobj->button = gtk_button_new_with_label ("Start thread"); g_signal_connect (G_OBJECT (callobj->button), "clicked", G_CALLBACK (startstop_thread), (gpointer) callobj); gtk_box_pack_start (GTK_BOX (vbox), callobj->button, TRUE, TRUE, 0); button = gtk_button_new_with_label ("Close"); g_signal_connect (button, "clicked", gtk_main_quit, NULL); gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0); /* Enter the main loop */ gtk_widget_show_all (callobj->win); gtk_main (); g_free (callobj); return 0; } _______________________________________________ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list