capturar salida consola

Rafael Villar Burke pachi en mmn-arquitectos.com
Mar Feb 15 20:23:52 CET 2005


Felipe Botet wrote:

>Hola,
>este es mi primer mensaje a la lista, así que saludos a todos.
>Mi pregunta es, posiblemente, simple, pero no encuentro respuesta por
>otros medios (google, tutorial pygtk, etc). Necesito lanzar un comando
>desde una aplicación pygtk y capturar su salida por consola a medida
>que se produzca y redirigirla a un textview, sin esperar a que
>concluya su trabajo, puesto que podría demorarse mucho.
>Concretamente el comando es "os.system('dpkg -i paquete.deb')".
>Alguien podria indicarme cómo hacerlo.
>
Ya te han ido contestando en la lista, pero he estado intentando 
resolver el problema sin usar hilos, con select.select() con pipes, 
evitando el bloqueo de la E/S hasta el final de la ejecución y vigilando 
la salida del proceso externo con gobject.add_io_watch(), pero parece 
que no tengo éxito y la solución no es para nada portable (aunque en tu 
caso parece importar poco), debido a que en Win32 las tuberías no 
soportan la API tradicional de select y no se pueden poner en modo de 
no-bloqueo...

He dejado la solución de abajo en la FAQ de pygtk en la entrada 14.23 
(http://www.async.com.br/faq/pygtk/index.py?req=show&file=faq14.023.htp), 
a la espera de que alguien más espabilado resuelva esto sin hilos :).

------------

#!/usr/bin/env python
"""Mostrar la salida de una orden externa en un control gtk.TextView sin 
bloquear la Interfaz de Usuaria"""

import os, threading, locale

import pygtk
pygtk.require('2.0')
import gtk

encoding = locale.getpreferredencoding()
utf8conv = lambda x : unicode(x, encoding).encode('utf8')

def on_button_clicked(button, buffer, command):
    thr = threading.Thread(target= read_output, args=(buffer, command))
    thr.run()
   
def read_output(buffer, command):
    stdin, stdouterr = os.popen4(command)
    for line in stdouterr.readlines():
        buffer.insert(buffer.get_end_iter(), utf8conv(line))

sw = gtk.ScrolledWindow()
sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
textview = gtk.TextView()
textbuffer = textview.get_buffer()
sw.add(textview)
win = gtk.Window()
win.resize(300,500)
win.connect('delete-event', gtk.main_quit)
button = gtk.Button(u"¡Púlsame!")
command = 'dir -R %s' % os.getcwd()
button.connect("clicked", on_button_clicked, textbuffer, command)
vbox = gtk.VBox()
vbox.pack_start(button, gtk.FALSE)
vbox.pack_start(sw)
win.add(vbox)
win.show_all()

gtk.main()

----------

Saludos,

Pachi




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