wxPopen.py
changeset 70 2767bc85aa9a
parent 48 6b30cfee163e
child 79 ae06c2da83f7
equal deleted inserted replaced
69:6a331a809986 70:2767bc85aa9a
    27 #
    27 #
    28 
    28 
    29 import time
    29 import time
    30 from StringIO import StringIO
    30 from StringIO import StringIO
    31 
    31 
    32 from wxPython.wx import *
    32 import wx
    33 
    33 
    34 class ProcessRunnerMix:
    34 class ProcessRunnerMix:
       
    35 
       
    36     if wx.VERSION < (2, 6, 0):
       
    37         def Bind(self, event, function, id = None):
       
    38             if id is not None:
       
    39                 event(self, id, function)
       
    40             else:
       
    41                 event(self, function)
       
    42     
    35     def __init__(self, input, handler=None):
    43     def __init__(self, input, handler=None):
    36         if handler is None:
    44         if handler is None:
    37             handler = self
    45             handler = self
    38         self.handler = handler    
    46         self.handler = handler    
    39         EVT_IDLE(handler, self.OnIdle)
    47         handler.Bind(wx.EVT_MENU, self.OnIdle)
    40         EVT_END_PROCESS(handler, -1, self.OnProcessEnded)
    48         handler.Bind(wx.EVT_END_PROCESS, self.OnProcessEnded, id=-1)
    41 
    49         
    42         input.reverse() # so we can pop
    50         input.reverse() # so we can pop
    43         self.input = input
    51         self.input = input
    44         
    52         
    45         self.reset()
    53         self.reset()
    46 
    54 
    53         self.errorStream = None
    61         self.errorStream = None
    54         self.outputStream = None
    62         self.outputStream = None
    55         self.outputFunc = None
    63         self.outputFunc = None
    56         self.errorsFunc = None
    64         self.errorsFunc = None
    57         self.finishedFunc = None
    65         self.finishedFunc = None
    58         self.finished = false
    66         self.finished = False
    59         self.responded = false
    67         self.responded = False
    60 
    68 
    61     def execute(self, cmd):
    69     def execute(self, cmd):
    62         self.process = wxProcess(self.handler)
    70         self.process = wx.Process(self.handler)
    63         self.process.Redirect()
    71         self.process.Redirect()
    64 
    72 
    65         self.pid = wxExecute(cmd, wxEXEC_NOHIDE, self.process)
    73         self.pid = wx.Execute(cmd, wx.EXEC_NOHIDE, self.process)
    66 
    74 
    67         self.inputStream = self.process.GetOutputStream()
    75         self.inputStream = self.process.GetOutputStream()
    68         self.errorStream = self.process.GetErrorStream()
    76         self.errorStream = self.process.GetErrorStream()
    69         self.outputStream = self.process.GetInputStream()
    77         self.outputStream = self.process.GetInputStream()
    70 
    78 
    71         #self.OnIdle()
    79         #self.OnIdle()
    72         wxWakeUpIdle()
    80         wx.WakeUpIdle()
    73     
    81     
    74     def setCallbacks(self, output, errors, finished):
    82     def setCallbacks(self, output, errors, finished):
    75         self.outputFunc = output
    83         self.outputFunc = output
    76         self.errorsFunc = errors
    84         self.errorsFunc = errors
    77         self.finishedFunc = finished
    85         self.finishedFunc = finished
    83             self.process = None
    91             self.process = None
    84 
    92 
    85     def kill(self):
    93     def kill(self):
    86         if self.process is not None:
    94         if self.process is not None:
    87             self.process.CloseOutput()
    95             self.process.CloseOutput()
    88             if wxProcess_Kill(self.pid, wxSIGTERM) != wxKILL_OK:
    96             if wx.Process_Kill(self.pid, wx.SIGTERM) != wx.KILL_OK:
    89                 wxProcess_Kill(self.pid, wxSIGKILL)
    97                 wx.Process_Kill(self.pid, wx.SIGKILL)
    90             self.process = None
    98             self.process = None
    91 
    99 
    92     def updateStream(self, stream, data):
   100     def updateStream(self, stream, data):
    93         if stream and stream.CanRead():
   101         if stream and stream.CanRead():
    94             if not self.responded:
   102             if not self.responded:
    95                 self.responded = true
   103                 self.responded = True
    96             text = stream.read()
   104             text = stream.read()
    97             data.append(text)
   105             data.append(text)
    98             return text
   106             return text
    99         else:
   107         else:
   100             return None
   108             return None
   113     def OnIdle(self, event=None):
   121     def OnIdle(self, event=None):
   114         if self.process is not None:
   122         if self.process is not None:
   115             self.updateInpStream(self.inputStream, self.input)
   123             self.updateInpStream(self.inputStream, self.input)
   116             e = self.updateErrStream(self.errorStream, self.errors)
   124             e = self.updateErrStream(self.errorStream, self.errors)
   117             if e is not None and self.errorsFunc is not None:
   125             if e is not None and self.errorsFunc is not None:
   118                 wxCallAfter(self.errorsFunc, e)
   126                 wx.CallAfter(self.errorsFunc, e)
   119             o = self.updateOutStream(self.outputStream, self.output)
   127             o = self.updateOutStream(self.outputStream, self.output)
   120             if o is not None and self.outputFunc is not None:
   128             if o is not None and self.outputFunc is not None:
   121                 wxCallAfter(self.outputFunc, o)
   129                 wx.CallAfter(self.outputFunc, o)
   122 
   130 
   123             #wxWakeUpIdle()
   131             #wx.WakeUpIdle()
   124             #time.sleep(0.001)
   132             #time.sleep(0.001)
   125 
   133 
   126     def OnProcessEnded(self, event):
   134     def OnProcessEnded(self, event):
   127         self.OnIdle()
   135         self.OnIdle()
   128         pid,exitcode = event.GetPid(), event.GetExitCode()
   136         pid,exitcode = event.GetPid(), event.GetExitCode()
   129         if self.process:
   137         if self.process:
   130             self.process.Destroy()
   138             self.process.Destroy()
   131             self.process = None
   139             self.process = None
   132 
   140 
   133         self.finished = true
   141         self.finished = True
   134         
   142         
   135         # XXX doesn't work ???
   143         # XXX doesn't work ???
   136         #self.handler.Disconnect(-1, wxEVT_IDLE)
   144         #self.handler.Disconnect(-1, wx.EVT_IDLE)
   137         
   145         
   138         if self.finishedFunc:
   146         if self.finishedFunc:
   139             wxCallAfter(self.finishedFunc, pid, exitcode)
   147             wx.CallAfter(self.finishedFunc, pid, exitcode)
   140 
   148 
   141 class ProcessRunner(wxEvtHandler, ProcessRunnerMix):
   149 class ProcessRunner(wx.EvtHandler, ProcessRunnerMix):
   142     def __init__(self, input):
   150     def __init__(self, input):
   143         wxEvtHandler.__init__(self)
   151         wx.EvtHandler.__init__(self)
   144         ProcessRunnerMix.__init__(self, input)
   152         ProcessRunnerMix.__init__(self, input)
   145 
   153 
   146 def wxPopen3(cmd, input, output, errors, finish, handler=None):
   154 def wxPopen3(cmd, input, output, errors, finish, handler=None):
   147     p = ProcessRunnerMix(input, handler)
   155     p = ProcessRunnerMix(input, handler)
   148     p.setCallbacks(output, errors, finish)
   156     p.setCallbacks(output, errors, finish)