]> git.saurik.com Git - wxWidgets.git/blob - wxPython/demo/wxProcess.py
wxPython metadata xml
[wxWidgets.git] / wxPython / demo / wxProcess.py
1 # 11/20/2003 - Jeff Grimmett (grimmtooth@softhome.net)
2 #
3 # o Updated for wx namespace
4 #
5
6 import wx
7
8 #----------------------------------------------------------------------
9
10 class TestPanel(wx.Panel):
11 def __init__(self, parent, ID, log):
12 wx.Panel.__init__(self, parent, ID)
13 self.log = log
14
15 self.process = None
16 self.Bind(wx.EVT_IDLE, self.OnIdle)
17
18 # We can either derive from wxProcess and override OnTerminate
19 # or we can let wxProcess send this window an event that is
20 # caught in the normal way...
21 self.Bind(wx.EVT_END_PROCESS, self.OnProcessEnded)
22
23
24 # Make the controls
25 prompt = wx.StaticText(self, -1, 'Command line:')
26 self.cmd = wx.TextCtrl(self, -1, 'python -u data/echo.py')
27 self.exBtn = wx.Button(self, -1, 'Execute')
28
29 self.out = wx.TextCtrl(self, -1, '', style=wx.TE_MULTILINE|wx.TE_READONLY)
30
31 self.inp = wx.TextCtrl(self, -1, '', style=wx.TE_PROCESS_ENTER)
32 self.sndBtn = wx.Button(self, -1, 'Send')
33 self.termBtn = wx.Button(self, -1, 'Close Stream')
34 self.inp.Enable(False)
35 self.sndBtn.Enable(False)
36 self.termBtn.Enable(False)
37
38 # Hook up the events
39 self.Bind(wx.EVT_BUTTON, self.OnExecuteBtn, self.exBtn)
40 self.Bind(wx.EVT_BUTTON, self.OnSendText, self.sndBtn)
41 self.Bind(wx.EVT_BUTTON, self.OnCloseStream, self.termBtn)
42 self.Bind(wx.EVT_TEXT_ENTER, self.OnSendText, self.inp)
43
44
45 # Do the layout
46 box1 = wx.BoxSizer(wx.HORIZONTAL)
47 box1.Add(prompt, 0, wx.ALIGN_CENTER)
48 box1.Add(self.cmd, 1, wx.ALIGN_CENTER|wx.LEFT|wx.RIGHT, 5)
49 box1.Add(self.exBtn, 0)
50
51 box2 = wx.BoxSizer(wx.HORIZONTAL)
52 box2.Add(self.inp, 1, wx.ALIGN_CENTER)
53 box2.Add(self.sndBtn, 0, wx.LEFT, 5)
54 box2.Add(self.termBtn, 0, wx.LEFT, 5)
55
56 sizer = wx.BoxSizer(wx.VERTICAL)
57 sizer.Add(box1, 0, wx.EXPAND|wx.ALL, 10)
58 sizer.Add(self.out, 1, wx.EXPAND|wx.ALL, 10)
59 sizer.Add(box2, 0, wx.EXPAND|wx.ALL, 10)
60
61 self.SetSizer(sizer)
62 self.SetAutoLayout(True)
63
64
65 def __del__(self):
66 if self.process is not None:
67 self.process.Detach()
68 self.process.CloseOutput()
69 self.process = None
70
71
72 def OnExecuteBtn(self, evt):
73 cmd = self.cmd.GetValue()
74
75 self.process = wx.Process(self)
76 self.process.Redirect();
77 pid = wx.Execute(cmd, wx.EXEC_ASYNC, self.process)
78 self.log.write('OnExecuteBtn: "%s" pid: %s\n' % (cmd, pid))
79
80 self.inp.Enable(True)
81 self.sndBtn.Enable(True)
82 self.termBtn.Enable(True)
83 self.cmd.Enable(False)
84 self.exBtn.Enable(False)
85 self.inp.SetFocus()
86
87
88 def OnSendText(self, evt):
89 text = self.inp.GetValue()
90 self.inp.SetValue('')
91 self.log.write('OnSendText: "%s"\n' % text)
92 self.process.GetOutputStream().write(text + '\n')
93 self.inp.SetFocus()
94
95
96 def OnCloseStream(self, evt):
97 self.log.write('OnCloseStream\n')
98 #print "b4 CloseOutput"
99 self.process.CloseOutput()
100 #print "after CloseOutput"
101
102 def OnIdle(self, evt):
103 if self.process is not None:
104 stream = self.process.GetInputStream()
105
106 if stream.CanRead():
107 text = stream.read()
108 self.out.AppendText(text)
109
110
111 def OnProcessEnded(self, evt):
112 self.log.write('OnProcessEnded, pid:%s, exitCode: %s\n' %
113 (evt.GetPid(), evt.GetExitCode()))
114
115 stream = self.process.GetInputStream()
116
117 if stream.CanRead():
118 text = stream.read()
119 self.out.AppendText(text)
120
121 self.process.Destroy()
122 self.process = None
123 self.inp.Enable(False)
124 self.sndBtn.Enable(False)
125 self.termBtn.Enable(False)
126 self.cmd.Enable(True)
127 self.exBtn.Enable(True)
128
129
130 #----------------------------------------------------------------------
131
132 def runTest(frame, nb, log):
133 win = TestPanel(nb, -1, log)
134 return win
135
136
137 #----------------------------------------------------------------------
138
139
140 overview = """\
141 <html><body>
142 <h2>wxProcess</h2>
143
144 wxProcess lets you get notified when an asyncronous child process
145 started by wxExecute terminates, and also to get input/output streams
146 for the child process's stdout, stderr and stdin.
147
148 <p>
149 This demo launches a simple python script that echos back on stdout
150 lines that it reads from stdin. You can send text to the echo
151 process' stdin by typing in the lower textctrl and clicking Send.
152
153 <p>
154 Clicking the Close Stream button will close the demo's end of the
155 stdin pipe to the child process. In our case that will cause the
156 child process to exit its main loop.
157
158 </body><html>
159 """
160
161
162 if __name__ == '__main__':
163 import sys,os
164 import run
165 run.main(['', os.path.basename(sys.argv[0])])