Welcome, guest | Sign In | My Account | Store | Cart

This is a straight port of tiny.m, from Garfinkel and Mahoney's "Building Cocoa Applications: A Step By Step Guide." It shows how to build a Cocoa application without using Interface Builder (or loading .nib files).

Python, 54 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
from math import sin, cos, pi
import objc
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:
      for g in loop:
        p1 = NSMakePoint(self.X(f), self.Y(f))
	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()
    

While Interface Builder is very nice for graphically laying out your user interface, sometimes it is more convenient to keep it all in the script. I've found that during the early iterations of a program I need to refactor drastically as I rethink the problem space, and trying to find all the connections in Interface Builder which have to be modified or renamed is a chore.

By delaying the use of IB until the program is more functional, it's more likely that you'll be able to design an appropriate interface. This can be a small bootstrap to get you started. This was my first PyObjC project, converting both the book example, and the PyObjC "Hello World" code. From it I was then able to use Python's file handling to build a graphical quote viewer quite easily, and ramp up from there.