This page has some hints on how to make your app more "Mac-like" on OS-X. See the bottom for a small sample app that implements all these methods.

Menus

Apple and Microsoft specify slightly different layouts for menubars. (Apple specification. Microsoft specification.) WxWidgets will automatically move certain menus on a Macintosh, to ease the task of writing cross-platform applications with native look and feel on both MS-Windows and Apple Macintosh; the wxWidgets default is Windows-like. The following code makes a "Help" menubar with an "About" item which will appear properly on both platforms:

That results in a "Help" menu on Windows, with "About MyApp" as a menu item (which is the Windows standard), and an "About MyApp" menu item in the Application menu on MacOS. (Note that it also creates an empty "Help" menu, but presumably you can fill that up with, well, Help. --MarcHedlund) There are similar tricks for Preferences and Quit menus, which are moved to the "Application" menu. See the sample below.

In addition, on the Macintosh, wxWidgets automatically creates the "Windows" menu, with a list of windows and "Minimize", "Zoom", and "Bring All to Front" items. This can be disabled by invoking the menubar's SetAutoWindowMenu method.

Creating an Application Bundle (.app)

Just like you can create stand alone executables on Windows, you can also make stand alone executables of your apps on Mac OS X, though it is a bit trickier due to compatibility issues between the various Mac OS X versions out there. Generally, the rule of thumb is that your stand alone executable should work on every version of OS X equal or greater to the version the executable was created on. Thus a .app bundle created on Jaguar would run on Panther, but one created on Panther would not run on Jaguar.

The old "BundleBuilder" module for making .app files is no longer supported or recommended. To make an .app on Mac now, use py2app. py2app 0.3.6 is current as of this writing. Unfortunately, the py2app project is somewhat confusing to learn; if you run into trouble, the pythonmac-sig mailing list is the best place to ask for help. The docs have gotten better, however.

The following setup.py excerpt works to create a wxPython-based .app under Python version 2.7; wxPython version 2.8.12.1; MacOS X 10.8.3 (Intel); py2app 0.7.3:

In setup file must be arch option because in new macs based on i5, i7 etc python most of the time is default in 64bit version and wx python don'like this.

Don't be scary by size of final file. Simple app containing about 350 lines get 80mb... If you don't need to run that app on PPC based processors try TrimTheFat to get smaller size.

I've generally found that trying to use one set of options for both py2app and py2exe is a good way to get frustrated. I have two blocks in my setup.py, one for Mac and one for Windows, and this block starts with if sys.platform == 'darwin': . --MarcHedlund

The py2app docs also discuss using py2app and py2exe with the same setup.py

Making your Application a Drop Target for Files

To make your application a drop target for files, you must do two things. The first is to override wx.App.MacOpenFile(string) to contain your code for loading the file. For example:

Once you do this, if you hold down the Option key and drag the file over your script, it will run the code in MacOpenFile. Why do you need to hold down option? Because you haven't yet gotten Mac OS X to recognize that you can open the files in your app. =) To do this, first create an application bundle as described in "Creating an Application Bundle", then add code like the following into the bundle's "info.plist" file (the below registers the htm and html file extensions):

Dropped Files on Startup

The above method doesn't work right for files dropped on the app's icon when the application is started. If you want to capture those (and you probably do), you want to use "argv emulation". Py2app sets this to true by default, and what it does is put the files dropped on the app at startup into sys.argv. They can then be handled just like you would file names passed in on a command line with a traditional command line *nix app.

In your app class implement the following message to get the callback for it:

Making it work correctly with the Dock

A Mac app should come to the foreground and show a window when it's Dock icon is clicked. This requires that you handle the kAEReopenApplication event, which wx has built in handling for. You need to add a MacReopenApp method to your App:

def MacReopenApp(self):
"""Called when the doc icon is clicked, and ???"""
self.GetTopWindow().Raise()

Which will raise the Top Window of your app. Your app may require something special, and you can put there in this method. Apple's HIG about this is here: APPLE HIG for Dock

Other Apple events

wx has a few more built in handlers for other system events that you may want to handle:

def MacNewFile(self):
pass
def MacPrintFile(self, file_path):
pass

There is also the wx.EVT_ACTIVATE_APP event, which yu may want to catch in your App object. I'm not entirely sure when it gets called, but I needed to do this to make it work right when another application was trying to raise my app with a system call. Without it, the app would not raise if it was minimized.

Putting it all together

Below is a simple app that does all the menus right, and handles drag and drop of files onto the app's icon in the doc or in the finder. (Tested on OS-X 10.4, Python 2.5, wxPython 2.8.1)

You can use any icon bundle named MacAppIcon.icns (I can't figure out how to enclosed a file here)

Accepting AppleEvent handlers that are not taken care

In MacOpenFile the respective AppleEvent handler is taken care of .. though what is with special things like to accept a pseudo protocol (GURL AppleEvent). In this case a custom wxPython Extension would have to be compiled .. the procedure is described on: Catching AppleEvents in wxMAC .. though at the moment the includes are a bit outdated thus its not compilable directly as is. also like before the correct Info.plist entrys would have to be made to register as ex the protocol to the application.

Older Versions of wxPython (< 2.6):

I've been unable to get the About/Preferences/Quit menu items defined correctly without calling:

the ampersand is mandatory. This is true even if your About menu item isn't in your Help menu - the help menu still needs to be set in order for About to work.

Scripting Other Applications

This isn't directly related to wxPython applications, but you can use Python to script applications which understand AppleScript using AppScript. This is a very useful tool for integrating your wxPython app with other Mac apps on the user's machine.