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