title: gobject and subprocess.Popen to communicate in a GTK GUI
body: <p>I am trying to use a gobject to allow communication between a Popen process and a GTK GUI.</p>
  
  <p>Inspired by this:
  <a href="https://pygabriel.wordpress.com/2009/07/27/redirecting-the-stdout-on-a-gtk-textview/#comment-156" rel="nofollow">https://pygabriel.wordpress.com/2009/07/27/redirecting-the-stdout-on-a-gtk-textview/#comment-156</a></p>
  
  <p>I implemented something similar to this:</p>
  
  <p><a href="http://hartree.altervista.org/files/command-textview.py" rel="nofollow">http://hartree.altervista.org/files/command-textview.py</a></p>
  
  <p>but I noticed that the gobject uses lots of CPU cycle even once the Popen process is terminated. Just run the scrip above and watch the Ubuntu System Monitor.</p>
  
  <p>After some work with "pty" I came up with this:</p>
  
  <pre><code>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()
  </code></pre>
  
  <p>The questions I have are:</p>
  
  <ul>
  <li><p>is pty a good idea? Can it be used for Windows too?</p></li>
  <li><p>is it possible to avoid using pty and just use stdout and not have the high CPU usage problem?</p></li>
  <li><p>if you run this scrip the first time it seems to buffer the txt output and give an incomplete output.</p></li>
  </ul>
  
  <p>Thank you for the help</p>