Recipe11.18.Building a Python Cocoa GUI Programmatically


Recipe 11.18. Building a Python Cocoa GUI Programmatically

Credit: Dethe Elza

Problem

You are developing a Python application using Mac OS X's Aqua interface (through Apple's Cocoa toolkit and the PyObjC, Python/Objective-C bridge). You want to build the application's user interface within the program itself (as is normally done in most other Python GUI toolkits), rather than via Apple's Interface Builder (IB) and resulting .nib files (as is usually done with Cocoa for Aqua applications).

Solution

Anything that you can do via Interface Builder and .nib files, you can also do directly in your program. Here is a simple demo:

from math import sin, cos, pi from Foundation import * from AppKit import * class DemoView(NSView):     n = 10     def X(self, t):         return (sin(t) + 1) * self.width * 0.5     def Y(self, t):         return (cos(t) + 1) * self.height * 0.5     def drawRect_(self, rect):         self.width = self.bounds( )[1][0]         self.height = self.bounds( )[1][1]         NSColor.whiteColor( ).set( )         NSRectFill(self.bounds( ))         NSColor.blackColor( ).set( )         step = 2 * pi/self.n         loop = [i * step for i in range(self.n)]         for f in loop:             p1 = NSMakePoint(self.X(f), self.Y(f))             for g in loop:                 p2 = NSMakePoint(self.X(g), self.Y(g))                 NSBezierPath.strokeLineFromPoint_toPoint_(p1, p2) class AppDelegate(NSObject):     def windowWillClose_(self, notification):         app.terminate_(self) def main( ):     global app     app = NSApplication.sharedApplication( )     graphicsRect = NSMakeRect(100.0, 350.0, 450.0, 400.0)     myWindow = NSWindow.alloc( ).initWithContentRect_styleMask_backing_defer_(         graphicsRect,         NSTitledWindowMask         | NSClosableWindowMask         | NSResizableWindowMask         | NSMiniaturizableWindowMask,         NSBackingStoreBuffered,         False)     myWindow.setTitle_('Tiny Application Window')     myView = DemoView.alloc( ).initWithFrame_(graphicsRect)     myWindow.setContentView_(myView)     myDelegate = AppDelegate.alloc( ).init( )     myWindow.setDelegate_(myDelegate)     myWindow.display( )     myWindow.orderFrontRegardless( )     app.run( )     print 'Done' if _ _name_ _ == '_ _main_ _':     main( )

Discussion

Most programmers prefer to lay out their programs' user interfaces graphically, and Apple's Interface Builder application, which comes with Apple's free Developer Tools (also known as XCode), is a particularly nice tool for this task (when you're using Apple's Cocoa toolkit to develop a GUI for Mac OS X's Aqua interface). (The PyObjC extension makes using Cocoa from Python an obvious choice, if you're developing applications for the Macintosh.)

Sometimes it is more convenient to keep all the GUI building within the very program I'm developing, at least at first. During the early iterations of developing a new program, I often need to refactor everything drastically as I rethink the problem space. When that happens, trying to find all the connections that have to be modified or renamed is a chore in Interface Builder or in any other such interactive GUI-painting application.

Some popular GUI toolkits, such as Tkinter, are based on the idea that the program builds its own GUI at startup by defining the needed objects and appropriately calling functions and methods. It may not be entirely clear to users of other toolkits, such as Cocoa, that just about every toolkit is capable of operating in a similar manner, allowing "programmatic" GUI construction. This applies even to those toolkits that are most often used by means of interactive GUI-painting applications. By delaying the use of IB until your program is more functional and stable, it's more likely that you'll be able to design an appropriate interface. This recipe can help get you started in that direction.

This recipe's code is a straight port of tiny.m, from Simson Garfinkel and Michael Mahoney, Building Cocoa Applications: A Step-by-Step Guide (O'Reilly), showing how to build a Cocoa application without using Interface Builder nor loading .nib files. This recipe was my first PyObjC project, and it is indebted both to the Cocoa book and to PyObjC's "Hello World" example code. Starting from this simple, almost toy-level recipe, I was able to use Python's file handling to easily build a graphical quote viewer and ramp up from there to building rich, full-fledged GUIs.

See Also

Garfinkel and Mahoney's Building Cocoa Applications: A Step-by-Step Guide (O'Reilly); PyObjC is at http://pyobjc.sourceforge.net/.



Python Cookbook
Python Cookbook
ISBN: 0596007973
EAN: 2147483647
Year: 2004
Pages: 420

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net