Ok, now I have some more comments. I have tried it, and it works fine
when the application sends output as newlines, but sometimes, it
prints a line and then waits to put some more output before the
newline, and then, the application locks up.
For example:

# /sbin/badblocks --vw /dev/testdevice
Checking for bad blocks in read-write mode
>From block 0 to 1007496
Testing with pattern 0xaa:

and then, Done is put on the end of the last line, and a newline is
added. But a new IO_IN event is triggered just as the line starts to
arrive, and readline() has to wait for the newline to arrive, while
the application is locked.

Any ideas? Thanks!!


2008/10/28 Roberto Cavada <[EMAIL PROTECTED]>:
> Néstor Amigo Cairo wrote:
>
>> Ok! I have tested this, and it only works at the end of the execution
>> of the command,
>
> There is a problem in the way you create your watcher's callback. You have
> to use a function, a method or a lambda. Try with this version of
> 'do_format'. It will also handle pipe error conditions.
> #-------------------------------------------
>  def do_format(self, widget, textbuffer):
>
>    def watcher(source, condition, buf):
>      if condition == gobject.IO_IN:
>        buf.insert(buf.get_end_iter(), source.readline())
>        return True # keep it watching
>      # error condition
>      buf.insert(buf.get_end_iter(), "<process died>\n")
>      return False # stop watching
>
>    proc = subprocess.Popen(("./prueba.sh"),
>                            shell=False,
>                            stdout=subprocess.PIPE,
>                           )
>    gobject.io_add_watch(proc.stdout,
>                         gobject.IO_IN | gobject.IO_ERR | gobject.IO_HUP,
>                         watcher, textbuffer)
>    return
> #-------------------------------------------
>
> Hope that helps.
> r.
>
>
>



-- 
Néstor
+34 687 96 74 81
[EMAIL PROTECTED]
#!/usr/bin/env python

# flashcopy

import pygtk
pygtk.require('2.0')
import gtk
import threading
import time
import subprocess
import gobject


gtk.gdk.threads_init()
gobject.threads_init()


class FormatThread(threading.Thread):

  stopthread = threading.Event()

  def init(self, textbuffer):
    self.textbuffer = textbuffer

  #def set(self, source, condition):
  def set(self, source):
    gtk.gdk.threads_enter()
    #self.textbuffer.insert(self.textbuffer.get_end_iter(), source.readline())
    self.textbuffer.insert(self.textbuffer.get_end_iter(), source)
    gtk.gdk.threads_leave()
    return True

  def run(self):
    proc = subprocess.Popen(("/sbin/badblocks", "-vw", "/dev/cardcf"),
    #proc = subprocess.Popen(("./prueba.sh"),
                            shell=False,
                            stdout=subprocess.PIPE,
                            stderr=subprocess.PIPE
                           )
    while True:
      line = proc.stderr.readline()
      if not line:
        print "Input is ended."
        break
      self.set(line)
    #gobject.io_add_watch(proc.stdout, gobject.IO_IN, self.set)
    #gobject.io_add_watch(proc.stderr, gobject.IO_IN, self.set)
    
  
  def stop(self):
    #Stop method, sets the event to terminate the thread's main loop
    self.stopthread.set()
         


class CopyThread(threading.Thread):

  stopthread = threading.Event()

  def init(self, textbuffer):
    self.textbuffer = textbuffer

  #def set(self, source, condition):
  def set(self, source):
    gtk.gdk.threads_enter()
    #self.textbuffer.insert(self.textbuffer.get_end_iter(), source.readline())
    self.textbuffer.insert(self.textbuffer.get_end_iter(), source)
    gtk.gdk.threads_leave()
    return True

  def run(self):
    proc = subprocess.Popen(("dd", "if=/target/sys_r45.img", "of=/dev/cardcf"),
                            shell=False,
                            stdout=subprocess.PIPE,
                            stderr=subprocess.PIPE
                           ) 
    gtk.gdk.threads_enter()
    self.textbuffer.insert(self.textbuffer.get_end_iter(), "Copying...")
    gtk.gdk.threads_leave()
    while True:
      line = proc.stdout.readline()
      if not line:
        print "Input is ended."
        break
      self.set(line)
    #gobject.io_add_watch(proc.stdout, gobject.IO_IN, self.set)
    #gobject.io_add_watch(proc.stderr, gobject.IO_IN, self.set)
    
  
  def stop(self):
    #Stop method, sets the event to terminate the thread's main loop
    self.stopthread.set()
         

class TextViewExample:
  
  def do_copy(self, widget, textbuffer):
    copy = CopyThread()
    copy.init(textbuffer)
    copy.start()
  
  def do_format(self, widget, textbuffer):
    """
    background = FormatThread()
    background.init(textbuffer)
    background.start()
    """
    
    def watcher(source, condition, buf):
      if condition == gobject.IO_IN:
        message = source.readline()
        buf.insert(buf.get_end_iter(), message)
        return True # keep it watching
    # error condition
      buf.insert(buf.get_end_iter(), "<process died>\n")
      return False # stop watching

    def watcher_err(source, condition, buf):
      if condition == gobject.IO_IN:
        message = source.readline()
        buf.insert(buf.get_end_iter(), message)
        return True # keep it watching
    # error condition
      buf.insert(buf.get_end_iter(), "<process died>\n")
      return False # stop watching
      
    proc = subprocess.Popen(("./prueba.sh"),
    #proc = subprocess.Popen(("/sbin/badblocks", "-vw", "/dev/cardcf"),
                           shell=False,
                           stdout=subprocess.PIPE,
                           stderr=subprocess.PIPE,
                          )
    gobject.io_add_watch(proc.stdout,
                        gobject.IO_IN | gobject.IO_ERR | gobject.IO_HUP,
                        watcher, textbuffer)
    
    gobject.io_add_watch(proc.stderr,
                        gobject.IO_IN | gobject.IO_ERR | gobject.IO_HUP,
                        watcher_err, textbuffer)
                        
    """md5sum_status, md5sum_output = commands.getstatusoutput('md5sum -c MD5SUMS')
    textbuffer.insert(textbuffer.get_end_iter(), str(md5sum_status))"""
    
  def close_application(self, widget):
    """main_quit function, it stops the thread and the gtk's main loop"""
    #Importing the fs object from the global scope
    #self.background.stop()
    gtk.main_quit()

  def __init__(self):
    window = gtk.Window(gtk.WINDOW_TOPLEVEL)
    window.set_resizable(True)  
    window.connect("destroy", self.close_application)
    window.set_title("TextView Widget Basic Example")
    window.set_border_width(0)

    box1 = gtk.VBox(False, 0)
    window.add(box1)
    box1.show()

    box2 = gtk.VBox(False, 10)
    box2.set_border_width(10)
    box1.pack_start(box2, True, True, 0)
    box2.show()

    sw = gtk.ScrolledWindow()
    sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
    textview = gtk.TextView()
    textbuffer = textview.get_buffer()
    sw.add(textview)
    sw.show()
    textview.set_editable(0)
    textview.set_cursor_visible(0)
    textview.show()

    box2.pack_start(sw)

    hbox = gtk.HButtonBox()
    box2.pack_start(hbox, False, False, 0)
    hbox.show()

    vbox = gtk.VBox()
    vbox.show()
    hbox.pack_start(vbox, False, False, 0)
    # check button to toggle editable mode
    copyButton = gtk.Button("Copy")
    vbox.pack_start(copyButton, False, False, 0)
    copyButton.connect("clicked", self.do_copy, textbuffer)
    copyButton.show()
    # radio buttons to specify wrap mode
    vbox = gtk.VBox()
    vbox.show()
    hbox.pack_start(vbox, False, False, 0)
    
    
    
    # check button to toggle editable mode
    formatButton = gtk.Button("Format")
    vbox.pack_start(formatButton, False, False, 0)
    formatButton.connect("clicked", self.do_format, textbuffer)
    formatButton.show()
    # radio buttons to specify wrap mode
    vbox = gtk.VBox()
    vbox.show()
    hbox.pack_start(vbox, False, False, 0)
    
    optionsButton = gtk.Button("Options")
    vbox.pack_start(optionsButton, False, True, 0)
    #radio.connect("toggled", self.new_wrap_mode, textview, gtk.WRAP_NONE)
    optionsButton.show()
        
    # radio buttons to specify justification
    vbox = gtk.VBox()
    vbox.show()
    hbox.pack_start(vbox, False, False, 0)
    upgradeButton = gtk.Button("Upgrade")
    vbox.pack_start(upgradeButton, False, True, 0)
    #radio.connect("toggled", self.new_justification, textview,
    #              gtk.JUSTIFY_LEFT)
    upgradeButton.show()

    separator = gtk.HSeparator()
    box1.pack_start(separator, False, True, 0)
    separator.show()

    box2 = gtk.VBox(False, 10)
    box2.set_border_width(10)
    box1.pack_start(box2, False, True, 0)
    box2.show()

    button = gtk.Button("close")
    button.connect("clicked", self.close_application)
    box2.pack_start(button, True, True, 0)
    button.set_flags(gtk.CAN_DEFAULT)
    button.grab_default()
    button.show()
    window.show()
    

def main():
  gtk.main()
  return 0       

if __name__ == "__main__":
  TextViewExample()
  main()

Attachment: prueba.sh
Description: Bourne shell script

_______________________________________________
pygtk mailing list   [email protected]
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://faq.pygtk.org/

Reply via email to