如何将NSSize和NSRect传递给PyObjC KVC便利存取器

时间:2011-12-09 07:05:06

标签: cocoa pyobjc key-value-coding

我正在Lion上的PyObjC中编写一些AppKit代码,我想使用特殊的KVC访问器样式,例如: obj._.field = value代替obj.setField_(value)

我已成功使用KVC设置NSString-和NSDictionary-valued属性,但是我遇到了包装Objective-C结构的问题,特别是NSSize和NSRect。

当我尝试设置NSSize或NSRect类型的KVC属性时,Objective-C层会抛出NSInvalidArgumentException。 Cocoa试图在Python对象上调用sizeValuerectValue

以下是交互式提示中显示问题的日志:

% python
Python 2.7.1 (r271:86832, Jul 31 2011, 19:30:53) 
[GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from AppKit import *
>>> NSApplication.sharedApplication()
<NSApplication: 0x7fcf6ae071f0>
>>> w = NSWindow.alloc().init()
>>> w._.minSize = NSSize(100, 200)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/PyObjC/objc/_convenience.py", line 141, in __setattr__
    return self.__object.setValue_forKey_(value, key)
ValueError: NSInvalidArgumentException - Class OC_PythonObject: no such selector: sizeValue
>>> r = NSMakeRect(100, 200, 300, 400)
>>> w._.frame=r
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/PyObjC/objc/_convenience.py", line 141, in __setattr__
    return self.__object.setValue_forKey_(value, key)
ValueError: NSInvalidArgumentException - Class OC_PythonObject: no such selector: rectValue

PyObjC似乎将结构包装在OC_PythonObject代理中,该代理不实现预期的KVC转换器。 KVC代码假定该值类似于NSValue并实现struct accessor方法。

有没有办法在PyObjC中设置结构值KVC属性?

1 个答案:

答案 0 :(得分:0)

这很简单。即使在普通的ObjC中,结构也需要在通过KVC之前用NSValue包裹。您可以在Python中执行相同的操作:

>>> w._.minSize = NSValue.valueWithSize_(NSSize(100,200))
>>> w.minSize()
<NSSize width=100.0 height=200.0>
>>> w._.frame = NSValue.valueWithRect_(NSMakeRect(100, 200, 300, 400))
>>> w.frame()
<NSRect origin=<NSPoint x=100.0 y=200.0> size=<NSSize width=300.0 height=400.0>>

有关详细信息,请参阅“KVC编程指南”中的"Wrapping and Unwrapping Structs"。此外,不要忘记在执行此操作时,并非所有类都符合KVC所有属性。

相关问题