J'essaie d'utiliser un objet gobject pour permettre la communication entre un processus Popen et une interface graphique GTK.gobject et subprocess.Popen pour communiquer dans une interface graphique GTK
Inspiré par ceci: https://pygabriel.wordpress.com/2009/07/27/redirecting-the-stdout-on-a-gtk-textview/#comment-156
Je mis en œuvre quelque chose de similaire à ceci:
http://hartree.altervista.org/files/command-textview.py
mais je remarquai que la gobject utilise beaucoup de cycle CPU, même une fois le processus Popen est mis fin. Il suffit de lancer le script ci-dessus et regarder le moniteur système Ubuntu.
Après quelques travaux avec "pty" je suis venu avec ceci:
import gtk,pygtk
import subprocess
import gobject
import pty, os, time
class CommandTextView(gtk.TextView):
def __init__(self):
super(CommandTextView,self).__init__()
self.master, self.slave = pty.openpty()
gobject.io_add_watch(os.fdopen(self.master), gobject.IO_IN, self.write_to_buffer)
self.proc = None
def run(self, w, cmd):
if self.proc == None or self.proc.poll() != None: # poll()=None means still running
self.proc = subprocess.Popen(cmd.split(), shell=True, stdout=self.slave, stderr=self.slave)
def stop(self,w):
if type(self.proc) is subprocess.Popen:
self.proc.kill()
while self.proc.poll() == None:
time.sleep(0.1)
self.proc = None
def write_to_buffer(self, fd, condition):
if condition == gobject.IO_IN:
char = fd.readline()
print 'adding:',char
buf = self.get_buffer()
buf.insert_at_cursor(char)
return True
else:
return False
def test():
win=gtk.Window()
vbox = gtk.VBox(False, 0)
win.set_size_request(300,300)
win.connect('delete-event',lambda w,e : gtk.main_quit())
ctv=CommandTextView()
bt1 = gtk.Button('Run')
bt2 = gtk.Button('Stop')
vbox.pack_start(ctv)
vbox.pack_end(bt2,False,False)
vbox.pack_end(bt1,False,False)
win.add(vbox)
bt1.connect("clicked", ctv.run, 'ls -la')
bt2.connect("clicked", ctv.stop)
win.show_all()
gtk.main()
if __name__=='__main__': test()
Les questions que je sont:
est pty une bonne idée? Peut-il être utilisé pour Windows aussi?
est-il possible d'éviter d'utiliser pty et juste utiliser stdout et ne pas avoir le problème d'utilisation de l'unité centrale élevée?
Si vous exécutez ce script la première fois, il semble mettre en tampon la sortie txt et donner une sortie incomplète.
Nous vous remercions de l'aide
Pouvez-vous nous en dire un peu plus sur ce que devrait être la solution? Je pense en fait que la commande self.proc.kill() ne tue pas le processus parce que j'utilise shell = True. Possible? – Fabrizio
Tout est possible. –
Cet exemple ne semble pas vraiment fonctionner si cmd = 'ls -R /' par exemple. Et pour le faire fonctionner avec lui, vous aurez peut-être besoin shell = False dans ce cas, le bouton d'arrêt ne fonctionnera pas. Bottom line, pas un si bel exemple de communication gui processus pygtk. – Fabrizio