Re: Multi-threaded GUI



On Thursday 05 October 2006 04:34, Melvin Newman wrote:
> My saga towards updating the GUI continues... the following are two code
> snippets:
>
> 1) My window update function. It is built into the window1 class and is
> supposed to update the main GUI window:
>
> gboolean window1::updater(gpointer data)
> {
>     /* Variables
>     ******************************************/
>         Glib::RefPtr<Gdk::Window>win = get_window();
>     /*****************************************/
>
>     if(win)
>     {
>         Gdk::Rectangle r(0, 0,
> get_allocation().get_width(),get_allocation().get_height());
>         win->invalidate_rect(r, false);
>     }
>     return(true);
> }
>
>
> 2) The following is my thread that calls this function through the
> g_idle_add() function... Unfortunately it does not compile at this line and
> being new to OO/C++ I have no idea why, or how to fix the problem:
>
> void *server_connect(void *ptr)
> {
>     /* Variables
>     ******************************************/
>         int tmp=0;
>         int socket_id;
>         struct sockaddr_in address;
>         gpointer data;
>         Glib::RefPtr<Gtk::TextBuffer> buffer;
>         sigc::connection pipe1;
>     /*****************************************/
>
>     socket_id = pthread_arg.socket_id;
>     address = pthread_arg.address;
>     buffer = pthread_arg.out_put_buffer;
>
>     do
>     {
>         tmp = connect (socket_id,(struct sockaddr *) &address,
> sizeof(struct sockaddr));
>         if (tmp <0)
>         {
>             buffer->insert_at_cursor("@");
>
>             g_idle_add(window1::updater,false);
>                ^-- Compiling stops here with: error: invalid use of
> non-static member function `gboolean window1::updater(void*)'
>
>             Glib::usleep(400000);
>         }
>
>     }while(tmp<0);
>
> }
>
> Unfortunately I cant seem to integrate the server_connect function into the
> class, because pthread then complains that it can not call it (miss mach
> type).
>
> Any help would be greatly appreciated.

If you are using (as it appears) the glibmm and gtkmm wrappers, then you ought 
to use Glib::SignalIdle class (and the convenience function 
Glib::signal_idle().connect()) rather than g_signal_idle().  Make sure your 
idle handler returns false.  See 
http://gtkmm.sourceforge.net/docs/glibmm-2.4/docs/reference/html/classGlib_1_1SignalIdle.html

You appear from your code snippet to be holding Gtkmm widgets in 
Glib::RefPtr<>s.  That is a no-no - they are only intended to hold objects 
which are GObjects, but not derived from GtkObject or GInitiallyUnowned 
(Gtk::Object or Glib::InitiallyUnowned in gtkmm-speak).  The reference 
counting will go awry if you put them into Glib::RefPtr<>s.

Alternatively it is quite straightforward to use unwrapped glib in C++ 
programs.  You can pass the this pointer of the class you are interested in 
as the data argument in g_signal_idle() (and any other glib/gtk+ event/signal 
handlers).  Make sure you declare your handler functions as extern "C" 
though, so that they have the correct linkage.  (gcc allows you to use static 
member functions in callbacks with C linkage, but not all compilers do.)

This has a few convenience things in it which I use, if you want to use 
unwrapped glib/GTK+/pthreads:

http://efax-gtk.cvs.sourceforge.net/efax-gtk/efax-gtk/src/utils/

Chris




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