Re: Signaling TreeView to update



On Thu, 2007-07-26 at 10:31 -0500, Joaquim Schmidlap wrote:
> On Wed, Jul 25, 2007 at 10:57:54AM -0500, Robert Caryl wrote:
> > Use a dispatcher in your GUI window that will call Gtk::Widget::queue_draw for
> > your Gtk::TreeView whenever your thread updates the Gtk::TreeModel displayed by
> > your Gtk::TreeView.
> 
> This worked, thank you. I'm still a bit confused why the Gtk event loop didn't
> just wake up on its own, but I'll accept this and move on.

Questions of this kind crop up about 2 or 3 times a month, and it
probably the FAQ of FAQs.  GTK+ is not of itself thread safe (although
there is a global lock you can use if your program runs only under
Unix-like OSes but NOT under windows - see
http://developer.gnome.org/doc/API/2.0/gdk/gdk-Threads.html ).

A typical symptom is that the GTK+ widget concerned will appear to
update itself if you, say, wave your mouse over it (which is the effect
you described), but eventually it will crash, usually with X complaining
about asynchronous events.

The work-around suggested to you is not safe either if (as it appears)
you are updating the Gtk::TreeModel from other than the GUI thread -
that depends on whether doing so invokes any GDK functions in the
updating thread, but I think it almost certainly does, via the internal
callbacks of the Gtk:TreeView object.  The suggested work-around does
the software equivalent of waving your mouse over it.  The best thing is
for the thread delivering data to put it onto a thread safe queue and
then emit from a Glib::Dispatcher object.  The callback of the
Glib::Dispatcher object can then extract from the queue and put the data
into the Gtk::TreeModel object - Glib::Dispatcher callbacks execute not
in the signalling thread, but in the thread in which the main program
loop runs, and is intended for this very purpose.  An alternative is to
go down to the C layer and use g_idle_add() - the glibmm version of this
is not thread safe for the reasons set out in this thread:
http://mail.gnome.org/archives/gtkmm-list/2007-January/msg00051.html

Either of these approaches also results in much cleaner programming than
trying to use the GDK global lock.  The thing about the global lock is
that if your program relies on it once in some obscure corner, you have
to use it everywhere.

Chris





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