Monthly Archives: March 2013

Very Simple OS X Cocoa Application using Python and Interface Builder

SimpleXibDemo

The Very Simple App

I’ve been playing around with creating a small Cocoa App for the last week or so. Finding good examples and documentation has been a little problematic, so I’ve put together a tiny application as a reference point to get going when starting fresh. It’s built entirely in Python using Cocoa through the PyObjC wrappers. It includes a XIB created with Interface Builder in Xcode. Bundling the App for distribution is a snap using the py2app command in setuptools.

Source on GitHub: simple_pyobjc_cocoa_xib

All the required Python:

The most useful resource for me has been the source available in the PyObjC examples. One thing that took a while to figure out was how the initial NIB and window are loaded when some of the examples start. The Info.plist file generated by py2app includes the NSMainNibFile element which instructs OS X to load the MainMenu NIB when launching by default.

The py2app tutorial has been useful for getting the initial project set up.

Below are the steps I took to create the application with a 5 minute video of the process at the bottom.

Create setup.py

The tool used to create a setup.py file is py2applet. It is not in the PATH by default so the full path can be used to run it.

 $ /System/Library/Frameworks/Python.framework/Versions/Current/Extras/bin/py2applet --make-setup SimpleXibDemo.py

By default, the setup.py created by py2applet has argv_emulation set to True. This flag enables dragging of files onto our application in OS X. It’s not supported with the latest libraries, and this application that functionality. So it can be removed from the OPTIONS dict.

To include the XIB that will be created later in the application, it’s added to the DATA_FILES list.

DATA_FILES = ['SimpleXibDemo.xib']

The Python Source

The Python source for the application is all in one file, SimpleXibDemo.py. It consists of one class (SimpleXibDemoControllerand a __main__ block to get the application up and running.

Inheriting from the NSWindowController class gives the SimpleXibDemoController class the responsibility of managing a window. It handles events like windowDidLoad to get hooks into the windows lifecycle.

The local variable counterTextField is initialized to objc.IBOutlet(). This allows in Interface builder to assign a reference to a Label to it for providing output to the user.

The @objc.IBAction decorators on a couple functions expose them to Interface Builder as so the functions can be called when a Push Button is activated.

Creating a XIB in Interface Builder

In Xcode, click File… New… File… Create and OS X User Interface Window. Save it with the file name that was referenced above in the setup.py; SimpleXibDemo.xib.

Drag three Push Button elements and one Label element into the new window. The buttons text can be changed by double clicking on them.

Window XIB Drag Buttons

Add the SimpleXibDemo.py file to Xcode in File… Add Files… Interface Builder will recognize the Python file and find the objc.IBOutlet() and @objc.IBAction elements.

Click on File’s Owner in the left pane with the projects objects and choose the identity inspector tab in the top right. Change the Class value to our Python class SimpleXibDemoController. 

Files Owner Class

Set the “File’s Owner” class

 

Attaching the IBOutlet and IBActions in Interface Builder:

Interface Builder dragging Actions Outlets

Hold down CTRL and drag from File’s Owner to the Label. Select the counterTextField outlet.

Hold down CTRL and drag from the decrement button to the File’s Owner. Select the decrement: action. Do the same for the increment button, but select the increment: action.

Hold down CTRL and drag fro the Quit button to the Application object and chose the terminate: action.

Run in Alias Mode for Development

While working on the App, it’s convenient to build it in Alias mode. Resources in the build are aliased to source code, so changes can be previewed without going through a whole rebuild.

$ python setup.py py2app -A

Run the application in Aliased mode:

$ dist/SimpleXibDemo.app/Contents/MacOS/SimpleXibDemo

Build for Distribution

The application is built for distribution using the same py2app command, but without the Alias flag.

$ python setup.py py2app

The distributable Application can be found in the dist folder.

Video of the workflow

 

Other ways to interact with our devices. Sight through tongue?

On Intelligence by Jeff Hawkins

In the book On Intelligence, Jeff Hawkins (founder of Palm Computing) makes the argument that the roughly about 30 billion neurons and 30 trillion synapses (junctions between neurons) in our brain are much like general purpose computers and can be trained to process information that they were not even initially supposed to.

Most of sight doesn’t happen in the eyes. The eyes are just sensors that feed data that is processed in the brain. As shown in the video below, Erik Weihenmayer has been able to regain some sight by using a Brainport device that takes video and sends signals to his tongue. From this, he’s about to “see” some objects around him, even read simple text, and play tic-tac-toe with his daughter.

This makes me wonder how the devices around us could be interacted with in more ways than just visually and audibly. For instance, Google Glass vibrates at the side of your head. Could it lead you around a city giving you directions not using the display at all? I can imagine different pulses in the vibrations let you know how soon you have to turn, and even different pulses would tell you to turn either left or right.

Brainport Vision Device helps a blind man “see”