Most of us love to distribute our python programs to others once you have finished coding a neat little script. For Windows users we package it using Py2exe or cx_freeze. However, many of the end-users will not be happy with a black command window popping up, say, when an error is thrown.
Of course the alternative is to write a full blown GUI application using WXPython or PyFLTK. Even the latter, though quite lightweight, adds several megabytes to the distribution, when all you need is a simple message-box indicating an error or showing some informational text. Clearly, its an overkill for your throwaway python scripts.
This is the kind of problem I typically face and I have found a good solution. The answer is ctypes library which comes as a part of the standard distribution from Python 2.5 onwards. It simply calls the messagebox function from user32.dll (which is always present in a windows installation). With the main problem solved, what remained was to obtain the error text and stack trace.
Let’s see how the code looks like:
# Importing all the works for a native Win32 Message Box
from ctypes import c_int, WINFUNCTYPE, windll
from ctypes.wintypes import HWND, LPCSTR, UINT
prototype = WINFUNCTYPE(c_int, HWND, LPCSTR, LPCSTR, UINT)
paramflags = (1, "hwnd", 0), (1, "text", "Hi"), (1, "caption", None), (1, "flags", 0)
MessageBox = prototype(("MessageBoxA", windll.user32), paramflags)
# For printing the stack
import sys
import traceback
from time import sleep
def show_popup(text):
print text
MessageBox(text=text, caption="Sample App Says...")
def mainloop():
raise "Uff!"
if __name__ == '__main__':
try:
mainloop()
except:
type, value, sys.last_traceback = sys.exc_info()
lines = traceback.format_exception(type, value,sys.last_traceback)
show_popup("Aiyooooo..... there has been an error!\n" +
"Exception in user code:\n" +
"".join(lines) +
"===== Please mail a screenshot to arunvr@gmail.com ===="
)
finally:
sleep(1) # show the console output for a second so that users can read it
EDIT: This is how it looks like in PyMail, one of my scripts-that-grew-into-an-app ;)