Re: Updating GUI during long operation



On Sat, 2013-04-20 at 18:54 +0200, Colomban Wendling wrote:
Just never do something time consuming in the main loop thread.  If you
don't there should not be any lag.  

Hey Colomban. The time consuming task is in its own separate thread, but
it's making a GIF animation lag and user interface responsiveness as
well.

And to communicate with the main
loop from another thread, the common technique is to add an idle handler
(that runs only once).  The GLib main loop is thread safe so you can
simply call g_idle_add() from the worker thread.

Yes, that's what I am currently doing.

I was using GObject.idle_add(self._updateGUI, ...) within the worker
thread to specify a function to be called regularly that could provide
some other GUI related update tasks, including the following within
it...

        # Pump the Gtk+ event handler...
        while Gtk.events_pending():
            Gtk.main_iteration()

That's a bad idea.  Forcing flush of pending events never is a real
solution, since at most it will perform everything that was queued, but
certainly not what will come.  And as you see yourself, it doesn't work
that well anyway.

I actually don't know how well it would work, if it wasn't for the stack
overflow crash as a result of the callback recursively calling itself
each iteration of Gtk.main_iteration() above.

However, my application will crash if I do this with a stack overflow
within updateGUI. I'm assuming that since idle_add posted the message to
call the updateGUI callback, when the callback is invoked and tries to
pump the message pipeline, the method is invoked again because it still
hasn't cleared itself from the queue.

That's weird, but yeah, since main_iteration() tells the main loop to
perform an iteration and you do this from an idle event I could imagine
your idle event calls itself recursively.  Again, just never use this
"workaround" method of forcing main loop iterations.

Ok, sounds good.

I could have tried this aforementioned event pump from outside the
updateGUI callback and done it from within the worker thread, but I
didn't know if that was thread safe to do.

I think the main loop is completely thread safe, event with this, but
again *do not do this*.  If the even loop freezes, it's that you do too
much work in it's thread, nothing else.  Check what you do in the main
thread and that takes time, and try either optimizing it or movie it to
another thread.

I think what I'll have to do is try optimizing the thread to give the
event pipeline a chance to "breath", but then that still begs the
question of the best way to do that. I thought of manually flushing the
event queue, but I don't think you can do that from the worker thread
and you mentioned it is not a good idea to do even if you could.

-- 
Kip Warner -- Software Engineer
OpenPGP encrypted/signed mail preferred
http://www.thevertigo.com


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