]>
Commit | Line | Data |
---|---|---|
c368d904 | 1 | |
8fa876ca | 2 | import wx |
c368d904 RD |
3 | |
4 | #---------------------------------------------------------------------- | |
5 | ||
8fa876ca | 6 | class TestPanel(wx.Panel): |
c368d904 | 7 | def __init__(self, parent, ID, log): |
8fa876ca | 8 | wx.Panel.__init__(self, parent, ID) |
c368d904 RD |
9 | self.log = log |
10 | ||
11 | self.process = None | |
8fa876ca | 12 | self.Bind(wx.EVT_IDLE, self.OnIdle) |
c368d904 | 13 | |
95bfd958 RD |
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 | |
c368d904 | 16 | # caught in the normal way... |
8fa876ca | 17 | self.Bind(wx.EVT_END_PROCESS, self.OnProcessEnded) |
c368d904 RD |
18 | |
19 | ||
20 | # Make the controls | |
8fa876ca RD |
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') | |
c368d904 | 24 | |
02b800ce RD |
25 | self.out = wx.TextCtrl(self, -1, '', |
26 | style=wx.TE_MULTILINE|wx.TE_READONLY|wx.TE_RICH2) | |
c368d904 | 27 | |
8fa876ca RD |
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') | |
1e4a197e RD |
31 | self.inp.Enable(False) |
32 | self.sndBtn.Enable(False) | |
33 | self.termBtn.Enable(False) | |
c368d904 RD |
34 | |
35 | # Hook up the events | |
8fa876ca RD |
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) | |
c368d904 RD |
40 | |
41 | ||
42 | # Do the layout | |
8fa876ca RD |
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) | |
c368d904 RD |
46 | box1.Add(self.exBtn, 0) |
47 | ||
8fa876ca RD |
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) | |
c368d904 | 52 | |
8fa876ca RD |
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) | |
c368d904 RD |
57 | |
58 | self.SetSizer(sizer) | |
1e4a197e | 59 | self.SetAutoLayout(True) |
c368d904 RD |
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 | ||
8fa876ca | 72 | self.process = wx.Process(self) |
c368d904 | 73 | self.process.Redirect(); |
8fa876ca | 74 | pid = wx.Execute(cmd, wx.EXEC_ASYNC, self.process) |
c368d904 RD |
75 | self.log.write('OnExecuteBtn: "%s" pid: %s\n' % (cmd, pid)) |
76 | ||
1e4a197e RD |
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) | |
c368d904 RD |
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') | |
a541c325 | 95 | #print "b4 CloseOutput" |
c368d904 | 96 | self.process.CloseOutput() |
a541c325 | 97 | #print "after CloseOutput" |
c368d904 RD |
98 | |
99 | def OnIdle(self, evt): | |
100 | if self.process is not None: | |
101 | stream = self.process.GetInputStream() | |
102 | ||
1e4a197e | 103 | if stream.CanRead(): |
c368d904 RD |
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() | |
8fa876ca | 113 | |
1e4a197e | 114 | if stream.CanRead(): |
c368d904 RD |
115 | text = stream.read() |
116 | self.out.AppendText(text) | |
117 | ||
118 | self.process.Destroy() | |
119 | self.process = None | |
1e4a197e RD |
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) | |
c368d904 RD |
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> | |
95bfd958 | 139 | <h2>wx.Process</h2> |
c368d904 | 140 | |
95bfd958 | 141 | wx.Process lets you get notified when an asyncronous child process |
c368d904 RD |
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 | """ | |
1fded56b RD |
157 | |
158 | ||
1fded56b RD |
159 | if __name__ == '__main__': |
160 | import sys,os | |
161 | import run | |
8eca4fef | 162 | run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:]) |