- #####################################################################
- # redirectText.py
- #
- # Created by Mike Driscoll
- #
- # Contact: mike@pythonlibrary.org
- # Website: http://www.blog.pythonlibrary.org
- #
- # Tested on Windows XP, Python 2.5.2, wxPython 2.8.9.1 (msw-unicode)
- #####################################################################
- import sys
- import os
- import wx
- import threading
- import time
- #import SomeModule1
- class RedirectText(object):
- def __init__(self,aWxTextCtrl):
- self.out=aWxTextCtrl
- def write(self,string):
- wx.CallAfter(self.out.WriteText, string)
- from subprocess import Popen, PIPE
- from threading import Thread
- from threading import Lock
- from Queue import Queue, Empty
- io_q = Queue()
- processList=[]
- lock = Lock()
- class StreamWatcher:
- def stdout_watcher(self, identifier, stream):
- #for line in stream:
- for line in iter(stream.readline,b''):
- print line
- if not stream.closed:
- stream.close()
- print "-i- Thread Terminating : ", identifier,"\n"
- def stderr_watcher(self, identifier, stream):
- #for line in stream:
- for line in iter(stream.readline,b''):
- print (identifier, line)
- if not stream.closed:
- stream.close()
- print "-i- Thread Terminating : ", identifier, "\n"
- import sys
- import subprocess
- import random
- import time
- import threading
- import Queue
- class AsynchronousFileReader(threading.Thread):
- '''
- Helper class to implement asynchronous reading of a file
- in a separate thread. Pushes read lines on a queue to
- be consumed in another thread.
- '''
- def __init__(self, fd, queue):
- assert isinstance(queue, Queue.Queue)
- assert callable(fd.readline)
- threading.Thread.__init__(self)
- self._fd = fd
- self._queue = queue
- def run(self):
- '''The body of the tread: read lines and put them on the queue.'''
- for line in iter(self._fd.readline, ''):
- self._queue.put(line)
- def eof(self):
- '''Check whether there is no more content to expect.'''
- isDead = not self.is_alive() and self._queue.empty()
- if isDead:
- self.join()
- self._fd.close()
- class MyGUI(wx.Frame):
- def __init__(self):
- wx.Frame.__init__(self, None, wx.ID_ANY, "wxPython Redirect Tutorial")
- # Add a panel so it looks the correct on all platforms
- panel = wx.Panel(self, wx.ID_ANY)
- log = wx.TextCtrl(panel, wx.ID_ANY, size=(300,100),
- style = wx.TE_MULTILINE|wx.TE_READONLY|wx.HSCROLL)
- btn = wx.Button(panel, wx.ID_ANY, 'Push me!')
- self.Bind(wx.EVT_BUTTON, self.onButton, btn)
- # Add widgets to a sizer
- sizer = wx.BoxSizer(wx.VERTICAL)
- sizer.Add(log, 1, wx.ALL|wx.EXPAND, 5)
- sizer.Add(btn, 0, wx.ALL|wx.CENTER, 5)
- panel.SetSizer(sizer)
- # redirect text here
- redir=RedirectText(log)
- sys.stdout=redir
- sys.stderr=redir
- self.stdout_queue = Queue.Queue()
- self.stderr_queue = Queue.Queue()
- def onButton(self, event):
- print ("-i- this is printed from GUI module itself")
- #SomeModule1.printSomething()
- PathToCurrentPythonInterpreter = os.path.abspath(os.path.join(sys.prefix, "python.exe"))
- modPath = os.path.abspath( os.path.join(os.path.abspath(os.path.dirname(__file__)),'SomeModule1.py') )
- print PathToCurrentPythonInterpreter
- print modPath
- proc = Popen([PathToCurrentPythonInterpreter, modPath], stdout=PIPE, stderr=PIPE, bufsize=1)
- #m=StreamWatcher()
- #n=StreamWatcher()
- #Thread(target=m.stdout_watcher, name='stdout-watcher', args=('STDOUT', proc.stdout, self.stdout_queue)).start()
- #Thread(target=n.stderr_watcher, name='stderr-watcher', args=('STDERR', proc.stderr, self.stderr_queue)).start()
- Thread(target=self.printerThread, name='stderr-watcher').start()
- stdout_reader = AsynchronousFileReader(proc.stdout, self.stdout_queue).start()
- stderr_reader = AsynchronousFileReader(proc.stderr, self.stderr_queue).start()
- #self.processList.append(proc)
- def printerThread(self):
- print "printer!"
- # Check the queues if we received some output (until there is nothing more to get).
- while True:
- # Show what we received from standard output.
- while not self.stdout_queue.empty():
- line = self.stdout_queue.get()
- print 'Received line on standard output: ' + repr(line)
- # Show what we received from standard error.
- while not self.stderr_queue.empty():
- line = self.stderr_queue.get()
- print 'Received line on standard error: ' + repr(line)
- # Sleep a bit before asking the readers again.
- time.sleep(.1)
- # Run the program
- if __name__ == "__main__":
- app = wx.PySimpleApp()
- frame = MyGUI().Show()
- app.MainLoop()