When Creating my Gallery Generation User Interface, I wanted to capture the output of my Gallery Generator that typically went to the terminal. I wanted to start the gallery Generator in its own thread then display its messages in a Scrolled window.
The General procedure is as follows:
1) Open a new Scrolled Window Dialog in the Main Thread
2) Start a new thread
3) use popen to start the other program and to capture its output (it is important that the program flush its output after every print, see Python code below, or else the scrolled window will only update after the program is finished)
4) In the
New Thread capture the program's output and put it in a thread-shared queue
5) In the
Main Thread Read the information out of the queue and display it in the Scrolled Window
It is important to open the scrolled Window in the Main thread or the wxWindowing system will go nuts. I thought that I would be able to create this effect without the queue, but now I believe it is required for cross thread communication.
Code:
import os, threading, sys, string, Queue
class HTML_dialog():
def generate(self):
generate_gallery_thread()
update_generate_dialog()
def generate_gallery_thread(self):
self.html_output_queue=Queue.Queue(2)
msg = _("")
self.generate_dialog = ScrolledMessageDialog(self.dialog, msg,
_("Biff's HTML Generation"),
67, 21, modal=False)
self.generate_dialog.add_line("Starting HTML Generation")
the_thread = threading.Thread(name = "Thread1", target=self.generate_gallery)
the_thread.start()
def generate_gallery(self):
print "starting gallery generator"
generate_output = os.popen('python ' + os.path.join(os.getcwd(),
'gallery_generator', 'generate.py') + " " + common.GetCurrentPath(),
'r')
while 1:
line = generate_output.readline()
if not line:
print "Breaking the write loop"
self.html_output_queue.put("Done HTML Generation")
break
line = string.strip(line)
print 'just read: %s' % line
self.html_output_queue.put(line, 1)
def update_generate_dialog(self):
while 1:
line = self.html_output_queue.get()
line = string.strip(line)
self.generate_dialog.add_line(line)
if line == "Done HTML Generation" : return
Then in the other program (in my case generate.py) flush the output with sys.stdout.flush()