2000-10-30 16:08:42 -05:00
|
|
|
|
2003-12-08 20:23:28 -05:00
|
|
|
import wx
|
2000-10-30 16:08:42 -05:00
|
|
|
|
|
|
|
#----------------------------------------------------------------------
|
|
|
|
|
2003-12-08 20:23:28 -05:00
|
|
|
class TestPanel(wx.Panel):
|
2000-10-30 16:08:42 -05:00
|
|
|
def __init__(self, parent, ID, log):
|
2003-12-08 20:23:28 -05:00
|
|
|
wx.Panel.__init__(self, parent, ID)
|
2000-10-30 16:08:42 -05:00
|
|
|
self.log = log
|
|
|
|
|
|
|
|
self.process = None
|
2003-12-08 20:23:28 -05:00
|
|
|
self.Bind(wx.EVT_IDLE, self.OnIdle)
|
2000-10-30 16:08:42 -05:00
|
|
|
|
2004-01-12 22:17:17 -05:00
|
|
|
# We can either derive from wx.Process and override OnTerminate
|
|
|
|
# or we can let wx.Process send this window an event that is
|
2000-10-30 16:08:42 -05:00
|
|
|
# caught in the normal way...
|
2003-12-08 20:23:28 -05:00
|
|
|
self.Bind(wx.EVT_END_PROCESS, self.OnProcessEnded)
|
2000-10-30 16:08:42 -05:00
|
|
|
|
|
|
|
|
|
|
|
# Make the controls
|
2003-12-08 20:23:28 -05:00
|
|
|
prompt = wx.StaticText(self, -1, 'Command line:')
|
|
|
|
self.cmd = wx.TextCtrl(self, -1, 'python -u data/echo.py')
|
|
|
|
self.exBtn = wx.Button(self, -1, 'Execute')
|
2000-10-30 16:08:42 -05:00
|
|
|
|
2005-12-30 18:02:03 -05:00
|
|
|
self.out = wx.TextCtrl(self, -1, '',
|
|
|
|
style=wx.TE_MULTILINE|wx.TE_READONLY|wx.TE_RICH2)
|
2000-10-30 16:08:42 -05:00
|
|
|
|
2003-12-08 20:23:28 -05:00
|
|
|
self.inp = wx.TextCtrl(self, -1, '', style=wx.TE_PROCESS_ENTER)
|
|
|
|
self.sndBtn = wx.Button(self, -1, 'Send')
|
|
|
|
self.termBtn = wx.Button(self, -1, 'Close Stream')
|
2003-03-25 01:35:27 -05:00
|
|
|
self.inp.Enable(False)
|
|
|
|
self.sndBtn.Enable(False)
|
|
|
|
self.termBtn.Enable(False)
|
2000-10-30 16:08:42 -05:00
|
|
|
|
|
|
|
# Hook up the events
|
2003-12-08 20:23:28 -05:00
|
|
|
self.Bind(wx.EVT_BUTTON, self.OnExecuteBtn, self.exBtn)
|
|
|
|
self.Bind(wx.EVT_BUTTON, self.OnSendText, self.sndBtn)
|
|
|
|
self.Bind(wx.EVT_BUTTON, self.OnCloseStream, self.termBtn)
|
|
|
|
self.Bind(wx.EVT_TEXT_ENTER, self.OnSendText, self.inp)
|
2000-10-30 16:08:42 -05:00
|
|
|
|
|
|
|
|
|
|
|
# Do the layout
|
2003-12-08 20:23:28 -05:00
|
|
|
box1 = wx.BoxSizer(wx.HORIZONTAL)
|
|
|
|
box1.Add(prompt, 0, wx.ALIGN_CENTER)
|
|
|
|
box1.Add(self.cmd, 1, wx.ALIGN_CENTER|wx.LEFT|wx.RIGHT, 5)
|
2000-10-30 16:08:42 -05:00
|
|
|
box1.Add(self.exBtn, 0)
|
|
|
|
|
2003-12-08 20:23:28 -05:00
|
|
|
box2 = wx.BoxSizer(wx.HORIZONTAL)
|
|
|
|
box2.Add(self.inp, 1, wx.ALIGN_CENTER)
|
|
|
|
box2.Add(self.sndBtn, 0, wx.LEFT, 5)
|
|
|
|
box2.Add(self.termBtn, 0, wx.LEFT, 5)
|
2000-10-30 16:08:42 -05:00
|
|
|
|
2003-12-08 20:23:28 -05:00
|
|
|
sizer = wx.BoxSizer(wx.VERTICAL)
|
|
|
|
sizer.Add(box1, 0, wx.EXPAND|wx.ALL, 10)
|
|
|
|
sizer.Add(self.out, 1, wx.EXPAND|wx.ALL, 10)
|
|
|
|
sizer.Add(box2, 0, wx.EXPAND|wx.ALL, 10)
|
2000-10-30 16:08:42 -05:00
|
|
|
|
|
|
|
self.SetSizer(sizer)
|
2003-03-25 01:35:27 -05:00
|
|
|
self.SetAutoLayout(True)
|
2000-10-30 16:08:42 -05:00
|
|
|
|
|
|
|
|
|
|
|
def __del__(self):
|
|
|
|
if self.process is not None:
|
|
|
|
self.process.Detach()
|
|
|
|
self.process.CloseOutput()
|
|
|
|
self.process = None
|
|
|
|
|
|
|
|
|
|
|
|
def OnExecuteBtn(self, evt):
|
|
|
|
cmd = self.cmd.GetValue()
|
|
|
|
|
2003-12-08 20:23:28 -05:00
|
|
|
self.process = wx.Process(self)
|
2000-10-30 16:08:42 -05:00
|
|
|
self.process.Redirect();
|
2003-12-08 20:23:28 -05:00
|
|
|
pid = wx.Execute(cmd, wx.EXEC_ASYNC, self.process)
|
2000-10-30 16:08:42 -05:00
|
|
|
self.log.write('OnExecuteBtn: "%s" pid: %s\n' % (cmd, pid))
|
|
|
|
|
2003-03-25 01:35:27 -05:00
|
|
|
self.inp.Enable(True)
|
|
|
|
self.sndBtn.Enable(True)
|
|
|
|
self.termBtn.Enable(True)
|
|
|
|
self.cmd.Enable(False)
|
|
|
|
self.exBtn.Enable(False)
|
2000-10-30 16:08:42 -05:00
|
|
|
self.inp.SetFocus()
|
|
|
|
|
|
|
|
|
|
|
|
def OnSendText(self, evt):
|
|
|
|
text = self.inp.GetValue()
|
|
|
|
self.inp.SetValue('')
|
|
|
|
self.log.write('OnSendText: "%s"\n' % text)
|
|
|
|
self.process.GetOutputStream().write(text + '\n')
|
|
|
|
self.inp.SetFocus()
|
|
|
|
|
|
|
|
|
|
|
|
def OnCloseStream(self, evt):
|
|
|
|
self.log.write('OnCloseStream\n')
|
2002-03-13 17:30:20 -05:00
|
|
|
#print "b4 CloseOutput"
|
2000-10-30 16:08:42 -05:00
|
|
|
self.process.CloseOutput()
|
2002-03-13 17:30:20 -05:00
|
|
|
#print "after CloseOutput"
|
2000-10-30 16:08:42 -05:00
|
|
|
|
|
|
|
def OnIdle(self, evt):
|
|
|
|
if self.process is not None:
|
|
|
|
stream = self.process.GetInputStream()
|
|
|
|
|
2003-03-25 01:35:27 -05:00
|
|
|
if stream.CanRead():
|
2000-10-30 16:08:42 -05:00
|
|
|
text = stream.read()
|
|
|
|
self.out.AppendText(text)
|
|
|
|
|
|
|
|
|
|
|
|
def OnProcessEnded(self, evt):
|
|
|
|
self.log.write('OnProcessEnded, pid:%s, exitCode: %s\n' %
|
|
|
|
(evt.GetPid(), evt.GetExitCode()))
|
|
|
|
|
|
|
|
stream = self.process.GetInputStream()
|
2003-12-08 20:23:28 -05:00
|
|
|
|
2003-03-25 01:35:27 -05:00
|
|
|
if stream.CanRead():
|
2000-10-30 16:08:42 -05:00
|
|
|
text = stream.read()
|
|
|
|
self.out.AppendText(text)
|
|
|
|
|
|
|
|
self.process.Destroy()
|
|
|
|
self.process = None
|
2003-03-25 01:35:27 -05:00
|
|
|
self.inp.Enable(False)
|
|
|
|
self.sndBtn.Enable(False)
|
|
|
|
self.termBtn.Enable(False)
|
|
|
|
self.cmd.Enable(True)
|
|
|
|
self.exBtn.Enable(True)
|
2000-10-30 16:08:42 -05:00
|
|
|
|
|
|
|
|
|
|
|
#----------------------------------------------------------------------
|
|
|
|
|
|
|
|
def runTest(frame, nb, log):
|
|
|
|
win = TestPanel(nb, -1, log)
|
|
|
|
return win
|
|
|
|
|
|
|
|
|
|
|
|
#----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
overview = """\
|
|
|
|
<html><body>
|
2004-01-12 22:17:17 -05:00
|
|
|
<h2>wx.Process</h2>
|
2000-10-30 16:08:42 -05:00
|
|
|
|
2004-01-12 22:17:17 -05:00
|
|
|
wx.Process lets you get notified when an asyncronous child process
|
2000-10-30 16:08:42 -05:00
|
|
|
started by wxExecute terminates, and also to get input/output streams
|
|
|
|
for the child process's stdout, stderr and stdin.
|
|
|
|
|
|
|
|
<p>
|
|
|
|
This demo launches a simple python script that echos back on stdout
|
|
|
|
lines that it reads from stdin. You can send text to the echo
|
|
|
|
process' stdin by typing in the lower textctrl and clicking Send.
|
|
|
|
|
|
|
|
<p>
|
|
|
|
Clicking the Close Stream button will close the demo's end of the
|
|
|
|
stdin pipe to the child process. In our case that will cause the
|
|
|
|
child process to exit its main loop.
|
|
|
|
|
|
|
|
</body><html>
|
|
|
|
"""
|
2003-07-02 19:13:10 -04:00
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
import sys,os
|
|
|
|
import run
|
2004-03-04 19:06:33 -05:00
|
|
|
run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
|