Gobject

Arnau Sanchez arnau en ehas.org
Sab Sep 22 16:09:30 CEST 2007


Eduardo Matus escribió:

> def play(self,opciones ,target):
>         mpc = "mplayer -slave -quiet \"" + target + "\" 2>/dev/null"
>         self.pin, self.pout = os.popen2(mpc)  #open pipe
>         self.startEofHandler()
> 
>     def startEofHandler(self):
>         self.eofHandler = gobject.io_add_watch(self.pout, gobject.IO_HUP,
> self.test)
> 
> 
>     def test(self,source,condition):
>         print 'Something happend!!'
>         print source
> 
> el proceso se ejecuta bien, se supone que cuando termina de reproducir
> cierto archivo, el metodo gobject.io_add_watch deberia gatillar al metodo
> test, pero no funciona :S alguna idea?

Lo malo del código con clases es que no podemos probarlo así sin más. 
Siempre es mejor enviar algo que corra.

En cuanto a popen2: existen os.system, os.spawn, os.popen, os.popen2, 
popen2.Popen2, popen2.Popen3, popen2.Popen4, y más que me dejo, pero 
desde python 2.4 se recomienda encarecidamente usar sólo subprocess. 
Este módulo es capaz de hacer lo mismo que todos los anteriores y aún más.

Como dice Rafael, es de imaginar que en algún punto de tu programa 
llamas al bucle de eventos. ¿Forma parte esto de una aplicación gtk?

A mi esto me funciona:

-------
#!/usr/bin/python
import subprocess
import gobject

def on_popen_hup(source, condition, popen):
     retcode = popen.wait()
     print "retcode:", retcode
     return False

def background_command(command):
     popen = subprocess.Popen(command, stdout=subprocess.PIPE,
         stderr=subprocess.STDOUT)
     gobject.io_add_watch(popen.stdout, gobject.IO_HUP, on_popen_hup,
         popen)

command = ["mplayer", "-slave", "-quiet", "goodfellas.avi"]
background_command(command)
gobject.MainLoop().run() # o gtk.main()
------

Una pregunta, ¿estás realmente usando la salida de mplayer o sólo es 
para ver cuándo acaba? si nadie lee del descriptor de salida, toda esa 
información queda en memoria y puede crecer sin control. Quizá no sea 
crítico en este caso (mplayer no escribe mucho), pero aún así...

Para esto último tienes dos opciones, a) decirle a io_add_watch que 
también vas a leer datos (y los lees en el manejador) o b) mandar la 
salida a /dev/null (en la llamada a subprocess) y en vez de utilizar 
io_add_watch, poner un manejador para capturar la señal SIGCHLD.

arnau




Más información sobre la lista de distribución Python-es