On 1 December 2011 15:55, Jérôme <jer...@jolimont.fr> wrote:
> Hi all.
>
> There's something a bit tricky about handler_block and subprocess.call I
> would like to understand.
>
> I'm writing a little program (a simplistic guitar tuner) that has six keys
> (buttons) all connected to a callback that plays sounds through the buzzer
> using a call to external function beep. When a key is pressed, beep is
> "subprocess.call"ed and plays a sound for 1000 ms.
>
> While the sound is played, further clicks on the key are sort of queued and
> played afterwards. If someone gets excited and clicks times and times, then
> the program keeps beeping for seconds until it is done. I don't want this.
>
> To avoid this, I figured out I could block the handler while the callback is
> calling beep. Therefore, I added calls to handler_block and handler_unblock
> at the beginning and end of the callback to disable the call to the callback
> itself.
>
> It does not work. It's as if the clicks are dealt with with a delay once the
> callback has returned.
>
> Now, as a comparison I tried to add delays inside my callback using the
> following code, found on the internet :
>
>        time_start = time.time()
>        time_end = (time_start + 1)
>        while time_end > time.time():
>                while gtk.events_pending():
>                        gtk.main_iteration()
>
> If I replace the call to beep by this delay, I get the expected result : the
> clicks are ignored when the handlers are blocked.

Remember that gtk is not threaded, so, unless the main loop gets a
chance to run, events aren't going to be processed. This delay
construct explicitly forces the main loop to process events, but a
call to subprocess.call will just block waiting for the command to
finish, and the main loop isn't going to run, so nothing clears the
event queue while waiting for the command to finish, and you'll get
the behavior you describe. Adding a "while gtk.events_pending():
gtk.main_iteration()" before reconnecting the handlers is a simple fix
for this, although completely blocking gtk's event loop does introduce
issues with redrawing and so forth.

I'd personally avoid the subprocess.call, and use subprocess.Popen
instead, polling the command in an gobject idle task or by using a
gobject.timer signal, and then reconnect handlers and cleanup when the
command finishes - this allows the gtk main loop to run as normal.

Hope that helps.

-- 
Neil Muller
drnlmul...@gmail.com

I've got a gmail account. Why haven't I become cool?
_______________________________________________
pygtk mailing list   pygtk@daa.com.au
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://faq.pygtk.org/

Reply via email to