Re: Problem running the GTK main loop in a separate thread (different from the main one).

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



OK. This works too:

#include <gtk/gtk.h>

static gpointer _gtkthread(gpointer a_data)
{
gdk_threads_enter();
gtk_main();
gdk_threads_leave();
return NULL;
}

static void _create_widgets()
{
GtkWidget *l_win;
GtkWidget *l_but;
gdk_threads_enter();
l_win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
l_but = gtk_button_new_with_label("My Button");
gtk_container_add(GTK_CONTAINER(l_win),l_but);
gtk_widget_show_all(l_win);
gdk_threads_leave();
}

int main(int a_argc,char **a_argv)
{
GThread *l_th;

g_thread_init(NULL);
gdk_threads_init();
gtk_init(&a_argc,&a_argv);
l_th = g_thread_create(_gtkthread,NULL,TRUE,NULL);
_create_widgets();
g_thread_join(l_th);

return 0;
}

Compile with: cc `pkg-config --cflags --libs gtk+-2.0 gthread-2.0` -o main main.c

There is no reason to wait for the main loop to start if the calls are within the gdk_threads_enter and gdk_threads_leave pair. Hope this help.

Atentamente,

Jorge Opaso Pazos
AUTOLogic LTDA




El 29-08-2009, a las 8:51, Cristi Cobzarenco escribió:

Hi,

Yeah, this works for me to, this is equivalent to my "create_in_gt" flag being on. Problem is if you try creating the widgets in the main thread.
Does this work for you?

#include <gtk/gtk.h>

static gpointer _gtkthread(gpointer a_data)
{
       gdk_threads_enter();
       gtk_main();
       gdk_threads_leave();
                                               
       return NULL;
}

int main(int a_argc,char **a_argv)
{
       GThread *l_th;
       GtkWidget *l_win;
       GtkWidget *l_but;

       g_thread_init(NULL);
       gdk_threads_init();
       gtk_init(&a_argc,&a_argv);
       l_th = g_thread_create(_gtkthread,NULL,TRUE,NULL);

       g_usleep(2000000); // wait two seconds to be sure that the main loop started
                       
       gdk_threads_enter();
       l_win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
       l_but = gtk_button_new_with_label("My Button");
       gtk_container_add(GTK_CONTAINER(l_win),l_but);
       gtk_widget_show_all(l_win);
       gdk_threads_leave();

       g_thread_join(l_th);

       return 0;
}

On Sat, Aug 29, 2009 at 3:45 PM, Jorge Opaso Pazos <jorge.opaso@xxxxxxxxx> wrote:
Hello,

This works for me:

#include <gtk/gtk.h>

static gpointer _gtkthread(gpointer a_data)
{
       GtkWidget *l_win;
       GtkWidget *l_but;
                       
       gdk_threads_enter();
       l_win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
       l_but = gtk_button_new_with_label("My Button");
       gtk_container_add(GTK_CONTAINER(l_win),l_but);
       gtk_widget_show_all(l_win);

       gtk_main();
       gdk_threads_leave();
                                               
       return NULL;
}

int main(int a_argc,char **a_argv)
{
       GThread *l_th;

       g_thread_init(NULL);
       gdk_threads_init();
       gtk_init(&a_argc,&a_argv);
       l_th = g_thread_create(_gtkthread,NULL,TRUE,NULL);
       g_thread_join(l_th);

       return 0;
}


Atentamente,

Jorge Opaso Pazos
AUTOLogic LTDA




El 29-08-2009, a las 7:35, Cristi Cobzarenco escribió:

Hi, I've been using GTK for a pretty long time but I've never used threads with it and I'm not able to properly run the GTK main loop in a separate thread.
More to the point if I create a window, for example, in a thread other than the GTK one, it becomes unresponsive. Other GTK calls (that don't create widgets) seem to work fine, however.
I've attached a sample program to show what I mean, the flag "create_in_gt" sets whether to create the widgets in the GTK thread or in the main one.

Is this normal behaviour, am I not supposed to do this, or is it a bug?

(NOTE: The first time I've sent this message it was detected as spam so I'll include the file instead of attaching it)

threadtest1.cpp:
#include <gtk/gtk.h>

const int create_in_gt = FALSE; // Whether to create the widgets in the GTK thread.
GtkWidget *win, *but;

// Creates a window with a button in it.
// This function will be called in the GTK thread if "create_in_gt" is TRUE
// or in the main thread otherwise.
int create_widgets(void*) {
   win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
   but = gtk_button_new_with_label("My Button");

   gtk_container_add(GTK_CONTAINER(win),but);
   gtk_widget_show_all(win);
   return FALSE;
}

// The GTK thread function
void* gtkthread(void *) {
   gdk_threads_enter(); // GTK calls to follow - locking.

   // Inits gtk in this thread (I have tried initing it in both threads, the
   // result is the same.)
   gtk_init(NULL,NULL);

   // Creates the widgets if neccesary and then enters the main loop.
   if( create_in_gt ) create_widgets(NULL);
   gtk_main();

   gdk_threads_leave(); // GTK calls end here - unlocking
}

int main(int argc, char *argv[]) {
   g_thread_init(NULL); // Init threads in main thread.
   gdk_threads_init();

   // Creates the GTK thread.
   GThread *gt = g_thread_create(gtkthread, NULL, TRUE,NULL);

   // Waits 1 second, creates widgets if neccesary then, waits 2 more seconds.
   g_usleep( 1000000 );
   if( !create_in_gt )
       g_idle_add(create_widgets,NULL);
   g_usleep( 2000000 );

   gdk_threads_enter(); // Quits GTK safely.
   gtk_main_quit();
   gdk_threads_leave();

   g_thread_join(gt); // Waits for GTK to quit.

   return 0;
}

--
Cristi Cobzarenco
_______________________________________________
gtk-list mailing list
gtk-list@xxxxxxxxx
http://mail.gnome.org/mailman/listinfo/gtk-list




--
Cristi Cobzarenco

_______________________________________________
gtk-list mailing list
gtk-list@xxxxxxxxx
http://mail.gnome.org/mailman/listinfo/gtk-list

[Index of Archives]     [Touch Screen Library]     [GIMP Users]     [Gnome]     [KDE]     [Yosemite News]     [Steve's Art]

  Powered by Linux