Получение объекта pyobjc из целочисленного идентификатора

Есть ли способ получить прокси-объект PyObjC для объекта Objective-C, учитывая только его id в виде целого числа? Можно ли это сделать без модуля расширения?

В моем случае я пытаюсь получить прокси-объект Cocoa из возвращаемого значения wx.Frame.GetHandle (используя wxMac с Cocoa).


person nneonneo    schedule 08.09.2012    source источник


Ответы (2)


Единственное решение, которое я нашел, основано на ctypes для создания объекта objc_object из 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)

Пример его использования для печати 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()

Это немного неприятно, так как использует ctypes. Если есть функция pyobjc API, которую я пропустил, или какой-то другой более изящный способ сделать это, я, безусловно, заинтересуюсь.

person nneonneo    schedule 08.09.2012
comment
Угу. Это должно работать, но это очень хрупко: будущие версии PyObjC могут не иметь функции PyObjCObject_New в расширении _objc. - person Ronald Oussoren; 22.02.2013

В PyObjC 2.5 вы можете использовать это:

import objc
objc.objc_object(ctypes_void_p=some_object_id)

В более ранних версиях PyObjC для этого нет общедоступного API.

person Ronald Oussoren    schedule 22.02.2013