2

Is there a way to get a PyObjC proxy object for an Objective-C object, given only its id as an integer? Can it be done without an extension module?

In my case, I'm trying to get a Cocoa proxy object from the return value of wx.Frame.GetHandle (using wxMac with Cocoa).

2 Answers 2

2

The one solution I did find relies on ctypes to create an objc_object object from the id:

import ctypes, objc
_objc = ctypes.PyDLL(objc._objc.__file__)

# PyObject *PyObjCObject_New(id objc_object, int flags, int retain)
_objc.PyObjCObject_New.restype = ctypes.py_object
_objc.PyObjCObject_New.argtypes = [ctypes.c_void_p, ctypes.c_int, ctypes.c_int]

def objc_object(id):
    return _objc.PyObjCObject_New(id, 0, 1)

An example of its use to print a wx.Frame:

import wx

class Frame(wx.Frame):
    def __init__(self, title):
        wx.Frame.__init__(self, None, title=title, pos=(150,150), size=(350,200))

        m_print = wx.Button(self, label="Print")
        m_print.Bind(wx.EVT_BUTTON, self.OnPrint)

    def OnPrint(self, event):
        topobj = objc_object(top.GetHandle())
        topobj.print_(None)

app = wx.App()
top = Frame(title="ObjC Test")
top.Show()

app.MainLoop()

It's a little nasty since it uses ctypes. If there's a pyobjc API function I overlooked or some other neater way to do it, I'd surely be interested.

Sign up to request clarification or add additional context in comments.

1 Comment

Yikes. This should work, but this is very fragile: future versions of PyObjC might not have a "PyObjCObject_New" function in the _objc extension.
1

In PyObjC 2.5 you can use this:

import objc
objc.objc_object(ctypes_void_p=some_object_id)

There is no public API for doing this in earlier versions of PyObjC.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.