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