Questions tagged [pyobjc]

PyObjC is a bridge between the Python and Objective-C programming languages. It allows code written in either one of those languages to interact more or less directly with code written in the other. Its primary use is in the creation of software for Mac OS X. The PyObjC package includes wrappers for Apple's Objective-C frameworks, and most of their C language APIs. It also includes project templates and file templates for use with Apple's IDE, Xcode.

PyObjC's about page explains potential advantages the bridge offers to developers in either language. The bridge allows custom Objective-C and Python code to be co-mingled (nearly) painlessly, so that each can be used where its strengths are greatest.

The most obvious advantage for Python developers is that it allows them to write applications for Mac OS X with native appearance and behaviors. The use of Apple's frameworks facilitates the creation of the expected user experience, while familiar Python modules are always available when needed. A Python class can be a subclass of any framework class.

Objective-C users may find some of their models and application logic to be easier to express succinctly in Python. In particular, the setup and access of NSArray and NSDictionary objects can be cumbersome. The bridge makes a Python list or dictionary able to be used any place that its Cocoa counterpart is expected. Python's literal lists and dictionaries, list comprehensions, iteration, and dictionary lookup syntax make sometimes awkward Objective-C constructions into elegant and readable code. Python code that uses the bridge will also manage the memory of any Cocoa object it uses.

An excellent five-part tutorial, written by Will Larson, can be found on his website, titled "An Epic Introduction to PyObjC and Cocoa". Like the bridge itself, the tutorial serves more as an introduction for Python users to Cocoa than the reverse, but is nonetheless worth reading for anyone who wants to use PyObjC.

The PyObjC Introduction goes through the basics of using the bridge. Where syntax differs, the bridge tends towards making Python code more like Objective-C code. Two syntax differences are worth singling out here: method calls and instance variable access, which can cause confusion for users of the bridge.

Objective-C's message-call syntax uses positional arguments, but the name of the method is actually interleaved with the arguments:

// The name of this method is "actOnArg:usingOtherArg:andThisOneToo:"
[anInstance actOnArg:arg1 usingOtherArg:arg2 andThisOneToo:arg3];

It seems obvious, then, to use Python's keyword argument feature to emulate this:

// The name of this method is "actOnArg", and it has keyword arguments
anInstance.actOnArg(arg1, usingOtherArg=arg2, andThisOneToo=arg3) 

However, because keyword arguments ignore position, it is not feasible to make this kind of translation. To Python, the following call is equivalent to the preceding one:

anInstance.actOnArg(arg1, andThisOneToo=arg3, usingOtherArg=arg2)

while the Objective-C call:

// The name of this method is "actOnArg:andThisOneToo:usingAnotherArg:"
[anInstance actOnArg:arg1 andThisOneToo:arg3 usingOtherArg:arg2];

refers to an entirely different method than the original example.

PyObjC's solution is to use underscores in place of colons in method names:

anInstance.actOnArg_usingOtherArg_andThisOneToo_(arg1, arg2, arg3)

which unambiguously represents the name of the Objective-C method. This, unavoidably, is one of the main warts of the bridge -- the verbosity of Cocoa method names sometimes causes unwieldy Python calls:

NSTimer.scheduledTimerWithTimeInterval_target_selector_userInfo_repeats_(1.0, self, objc.selector(self.actOnTimer_, signature='v@:@'), timerInfoDict, False)

As for instance variables, Objective-C has a separate namespace in each class for instance variables and method names, where Python has only one. A class in Objective-C can, and by convention does, have a method with the same name as an instance variable, which is a getter for that variable:

@interface MyObject : NSObject {
    int someIvar;
}
- (int)someIvar;
- (void)setSomeIvar:(int)newVal;   // The setter method for this ivar

Whereas this is impossible in Python. Python convention is to access instance variables directly, using the dot syntax:

anInstance.someIvar
anInstance.someIvar = 10

This especially causes confusion with the Objective-C 2.0 dot syntax, which is sugar for the standard accessor method:

anInstance.someIvar;         // Equivalent to [anInstance someIvar];
anInstance.someIvar = 10;    // Equivalent to [anInstance setSomeIvar:10];

PyObjC is forced to have its own convention, which is to give the ivar the name of the setter method, but prefixed with a single underscore. The convenience function objc.synthesize("someIvar") will create the ivar, the setter method, and the getter method with the expected names.

The PyObjC source is available and well worth a perusal; it especially repays investigation when getting into the trickier areas of the bridge, such as Objective-C methods which use out or plain-C parameters. In addition, the default Apple installation of PyObjC lags behind the latest version. On Snow Leopard particularly, this means that the bridge does not include some information needed to use new features of Apple's frameworks. (See "Problem with openPanelDidEnd" here on SO for an example.) That information is fortunately easily updated.

378 questions
37
votes
9 answers

How to put a tkinter window on top of the others?

I'm using Python 2 with Tkinter and PyObjC, and then I'm using py2app. The program is working fine, but the window starts as hidden whenever I open the program, so it doesn't appear until I click on the icon on the dock to bring it up. Is there…
Dennis
  • 3,506
  • 5
  • 34
  • 42
30
votes
3 answers

How to get selected item of NSOutlineView without using NSTreeController?

How do I get the selected item of an NSOutlineView with using my own data source. I see I can get selectedRow but it returns a row ID relative to the state of the outline. The only way to do it is to track the expanded collapsed state of the items,…
Ronaldo Nascimento
  • 1,571
  • 3
  • 21
  • 40
24
votes
10 answers

ImportError: No module named Foundation

I am trying to follow the instructions for the accepted answer to "PyObjC development with Xcode 3.2". I will repost them here since I don't have enough rep to comment on the actual question: Here's what I have done to get PyObjC working in Snow…
Chris Redford
  • 16,982
  • 21
  • 89
  • 109
23
votes
1 answer

PyObjC on iPhone (iOS5) broken?

Anybody knows how to fix PyObjC on iPhone 4s running iOS 5.0.1? On my iPhone 4 with iOS 4.2.1 everything was working perfectly. On the iPhone 4s with iOS 5.0.1 (and all the (same) packages installed) the PyObjC stuff does not work. The error I get…
Gik
  • 528
  • 5
  • 18
23
votes
1 answer

NSEvent global event monitoring in background

I am writing a simple Mac application designed to run in the background and perform certain actions whenever the user clicks the mouse button. The app is written in Python using PyObjC. I am using addGlobalMonitorForEventsMatchingMask to watch for…
ekl
  • 1,052
  • 2
  • 9
  • 24
18
votes
1 answer

Changing DNS settings using PyObjC

I'm trying to change the DNS servers on my Mac (10.10.4) using PyObjC (3.0.4). Everything seems to work: I get an authentication dialog prompting that my program is trying to change network settings, and the commit/apply commands return True, which…
robertklep
  • 198,204
  • 35
  • 394
  • 381
17
votes
9 answers

Why is the PyObjC documentation so bad?

For example, http://developer.apple.com/cocoa/pyobjc.html is still for OS X 10.4 Tiger, not 10.5 Leopard.. And that's the official Apple documentation for it.. The official PyObjC page is equally bad, http://pyobjc.sourceforge.net/ It's so bad it's…
dbr
  • 165,801
  • 69
  • 278
  • 343
16
votes
1 answer

How can I minimize/maximize windows in macOS with the Cocoa API from a Python script?

How can I minimize/maximize windows in macOS from a Python script? On Windows, there's a win32 api (the ShowWindow() function) that can do this. I'd like the macOS equivalent. I'd like to have a script be able to find a window from its title, then …
Al Sweigart
  • 11,566
  • 10
  • 64
  • 92
16
votes
3 answers

PyObjC development with Xcode 3.2

Xcode 3.2 has removed the default templates for the scripting languages (Ruby, Python etc). How do I find these templates to use in Xcode 3.2? Would I need to add anything else to Xcode to support working with and 'building' PyObjC…
Josh Hunt
  • 14,225
  • 26
  • 79
  • 98
13
votes
3 answers

PyObjC on Xcode 4

Xcode 3 had templates for building Cocoa subclasses in Python. I've recently upgraded to Xcode 4 but I cannot find out how I can use other languages besides the C family (C, C++, Obj-C) in Xcode 4. Does anyone know?
Jaliborc
  • 353
  • 5
  • 16
13
votes
8 answers

What are the downsides of using Python instead of Objective-C?

I know some Python and I'm really impressed by the language's ease of use. From what I've seen of Objective-C it looks a lot less pretty, but it seems to be the lingua franca for Mac OS X development (which means it has better documentation). I'm…
Wander Nauta
  • 18,832
  • 1
  • 45
  • 62
12
votes
1 answer

Embed python in to iOS (iphone) app written in Objective-C/Swift/C/C++ (whatever language i can compile in Xcode and bridge to iOS)

I Do Not Intend To Put The Project On The App Store Short Question - is there any up-to-date PyObjC tutorial for embedding python scripts into an iOS app written in Objective-C and/or swift? If not if there any up-to-date method for achieving the…
Shaun
  • 804
  • 2
  • 8
  • 16
12
votes
6 answers

PyObjc and Cocoa on Snow Leopard

I am about to start my A-Level Computing project (High School Level) which will hopefully be a point-of-sale application for Mac OS. Unfortunately, Objective-C is a little out of my league at the moment and should I get stuck with it in the project…
danpalmer
  • 2,163
  • 4
  • 24
  • 41
11
votes
2 answers

How to capture frames from Apple iSight using Python and PyObjC?

I am trying to capture a single frame from the Apple iSight camera built into a Macbook Pro using Python (version 2.7 or 2.6) and the PyObjC (version 2.2). As a starting point, I used this old StackOverflow question. To verify that it makes…
mrmekon
  • 373
  • 2
  • 9
11
votes
3 answers

How can I listen for a mouse event in Python on Mac?

I need to listen for global mouse events(not bound to an app) on my Mac in an app written in Python. I'm using PyObjC, but I can't figure out how to do it. Plain ObjC examples or other Python techniques also appreciated. My code so far: from Quartz…
Pepijn
  • 4,145
  • 5
  • 36
  • 64
1
2 3
25 26