Recipe 11.17. Getting User Input on Mac OS
Credit: Matteo Rattotti
Problem
You're writing a simple
application to run on Mac OS and want to get an input value from the
user without frightening the user by opening a scary terminal window.
Solution
Many Mac OS users are frightened by the terminal, so Python scripts
that require simple input from the user shouldn't
rely on normal textual input but rather should use the
EasyDialogs module from the Python Standard
Library. Here is an example, a simple image converter and resizer
application:
import os, sys, EasyDialogs, Image
# instead of relying on sys.argv, ask the user via a simple dialog:
rotater = ('Rotate right', 'Rotate image by 90 degrees clockwise')
rotatel = ('Rotate left', 'Rotate image by 90 degrees anti-clockwise')
scale = ('Makethumb', 'Make a 100x100 thumbnail')
str = ['Format JPG', 'Format PNG']
cmd = [rotater, rotatel, scale]
optlist = EasyDialogs.GetArgv(str, cmd,
addoldfile=False, addnewfile=False, addfolder=True)
# now we can parse the arguments and options (we could use getopt, too):
dirs = [ ]
format = "JPEG"
rotationr = False
rotationl = False
resize = False
for arg in optlist:
if arg == "--Format JPG":
format = "JPEG"
if arg == "--Format PNG":
format = "PNG"
if arg == "Rotate right":
rotationr = True
if arg == "Rotate left":
rotationl = True
if arg == "Makethumb":
resize = True
if os.path.isdir(arg):
dirs.append(arg)
if len(dirs) == 0:
EasyDialogs.Message("No directories specified")
sys.exit(0)
# Now, another, simpler dialog, uses the system's folder-chooser dialog:
path = EasyDialogs.AskFolder("Choose destination directory")
if not path:
sys.exit(0)
if not os.path.isdir(path) :
EasyDialogs.Message("Destination directory not found")
sys.exit(0)
# and now a progress bar:
tot_numfiles = sum([ len(os.listdir(d)) for d in dirs ])
bar = EasyDialogs.ProgressBar("Processing", tot_numfiles)
for d in dirs:
for item in os.listdir(d):
bar.inc( )
try:
objpict = Image.open(d + "/" + item)
if resize: objpict.thumbnail((100, 100, 1))
if rotationr: objpict = objpict.rotate(-90)
if rotationl: objpict = objpict.rotate(90)
objpict.save(path + "/" + item + "." + format, format)
except:
print item + " is not an image"
# and one last dialog...:
score = EasyDialogs.AskYesNoCancel("Do you like this program?")
if score == 1:
EasyDialogs.Message("Wwowowowow, EasyDialog roolz, ;-)")
elif score == 0:
EasyDialogs.Message("Sigh, sorry, will do better next time!-(")
elif score == -1:
EasyDialogs.Message("Hey, you didn't answer?!")
Discussion
This recipe's program is quite trivial, mostly meant
to show how to use a few of the dialogs in the
EasyDialogs standard library module for the Mac.
You could add quite a few more features, or do a better job of
implementing some of those in this recipe, for example, by using
getopt from the Python Standard Library to parse
the arguments and options, rather than the roll-your-own approach
we've taken.Since EasyDialogs is in the Python Standard
Library for the Mac, you can count on finding that module, as well as
Python itself, in any Mac that runs Mac OS X 10.3 Pantherand
that's well over ten million Macs, according to
Apple. Just build your script into an application with
bundlebuilder or, even better, with
py2app and distutils. Doing so
will enable you to distribute your Python application so that users
can park it in the Dock, use drag-and-drop from the Finder to give it
arguments, and so on. Documentation for both
bundlebuilder and py2app can be
found on the Wiki at http://www.pythonmac.org/wiki.The EasyDialogs module in the Python Standard
Library works only on the Mac, but if you like the concept, you can
try out Jimmy Retzlaff's port of that module to
Windows, available for download at http://www.averdevelopment.com/python/EasyDialogsl.
See Also
Library Reference documentation on
EasyDialogs; http://www.pythonmac.org/wiki for more
information on Python for Mac resources; py2app is
at http://undefined.org/python/;
http://www.averdevelopment.com/python/EasyDialogsl
for a port of EasyDialogs to Microsoft Windows.