On 11/25/05, Fredrik Lundh <[EMAIL PROTECTED]> wrote: > "metiu" wrote: > > > you have a compression utility that works as a standard *nix filter, so > > it takes something from stdin and gives it back compressed to stdout > > you like to use it as such, because it's nice to call it from the > > command line > > > > now someone finds your utility quite nice, and says it would be nice to > > have a GUI that shows you, for example, how long it will take to > > compress... > > > > one way for sure it would be to fork your app, but this would be a > > waste of time > > > > you'd like to reuse the compression library you've already written for > > your GUI and your console, but: > > - you'd like to have your console app clean and simple, such as: > > > > import sys > > import CompressLib > > > > data = sys.stdin.read() > > cdata = CompressLib.compress(data) > > print cdata > > > > but you'd like the GUI to show some progress and status info. > > here's a simple, stupid, and portable solution. the first script simulates > your compression utility: > > # compress.py (simulator) > > import time, sys > > for i in range(100): > sys.stdout.write(".") > sys.stderr.write("%d%% done\r" % i) > sys.stderr.flush() > time.sleep(0.1) > > (it prints "N% done" messages to stderr during the compression) > > the second script simulates your GUI. the stuff in the while loop should > be run by a timer/alarm function, at regular intervals: > > import re, subprocess, time, os > > class monitor: > # looks for "N% done" messages in the output stream > def __init__(self, tfile): > # could use dup/reopen instead > self.file = open(tfile.name, "r") > def poll(self): > pos = self.file.tell() > data = self.file.read() > if data: > data = re.findall("(\d+)% done", data) > if not data: > self.file.seek(pos) > else: > return int(data[-1]) > def close(self): > self.file.close() > > ifile = open("in.txt", "rb") > ofile = open("out.dat", "wb") > tfile = open("out.tmp~", "wb") > > p = subprocess.Popen( > "python compress.py", > stdin=ifile, stdout=ofile, stderr=tfile, > ) > > m = monitor(tfile) > > while 1: > # this should be placed in a background task that's called > # every second or so > if p.poll() is not None: > print "DONE" > break > status = m.poll() > if status is not None: > # update status monitor > print status, "PERCENT DONE" > # wait a while before calling the background task again > print "." > time.sleep(0.5) > > # clean up > ifile.close() > ofile.close() > m.close() > name = tfile.name > tfile.close() > os.remove(name) > > if you limit yourself to Unix only, you can simplify things quite a bit (e.g. > using a pipe instead of the temporary file and use select to poll it, or use > dup/reopen tricks to avoid opening the temporary file twice; if you do > the latter, you can also use safe tempfile creation methods (see the > "tempfile" method for details. etc). > > hope this helps! > > </F> > >
If you are using wxPython, you can skip writing this scaffolding yourself and use wx.Execute and wx.Process, which will allow you to execute other processes and re-direct thier input and output. The wxPython demo has an example. > > -- > http://mail.python.org/mailman/listinfo/python-list > -- http://mail.python.org/mailman/listinfo/python-list