我试图破解一个工具来为我的游戏可视化着色器,我想我会尝试使用python和cocoa。我碰到了一堵砖墙。也许是我对目标c的理解有点差,但我似乎无法将这段代码用于我试图编写的视图:
from objc import YES, NO, IBAction, IBOutlet
from Foundation import *
from AppKit import *
import gv
class SceneView(NSOpenGLView):
def __init__(self):
NSOpenGLView.__init__(self)
self.renderer = None
def doinit(self):
self.renderer = gv.CoreRenderer()
def initWithFrame_(self, frame):
self = super(SceneView, self).initWithFrame_(frame)
if self:
self.doinit()
print self.__dict__
return self
def drawRect_(self, rect):
clearColor = [0.0,0.0,0.0,0.0]
print self.__dict__
self.renderer.clear(CF_Target|CF_ZBuffer,clearColor)
执行时输出:
{'renderer': <gv.CoreRenderer; proxy of <Swig Object of type 'GV::CoreRenderer *' at 0x202c7d0> >}
{}
2009-04-03 19:13:30.941 geom-view-edit[50154:10b] An exception has occured:
Traceback (most recent call last):
File "/System/Library/Frameworks/Python.framework/Versions/2.5/Extras/lib/python/PyObjCTools/AppHelper.py", line 235, in runEventLoop
File "/mnt/gilead/amcharg/projects/geom-view-edit/build/Debug/geom-view-edit.app/Contents/Resources/SceneView.py", line 37, in drawRect_
self.renderer.clear(CF_Target|CF_ZBuffer,clearColor)
AttributeError: 'SceneView' object has no attribute 'renderer'
似乎丢失了我的渲染器变量,考虑到initWithFrame_代码有多么简单,这并不令人惊讶,但这是xcode似乎写的东西,我认为这是有道理的,因为目标C将init与alloc惯用语分开。然而,看到它的蟒蛇仍然很奇怪。
是否有任何方法可以挽救这一点,还是应该在代码棚后面拍摄并使用QT或wxPython?我考虑过使用objective-c,但我想测试一下我刚编译的这些漂亮的swig绑定=)
答案 0 :(得分:3)
根据您应用中其他位置发生的情况,您的实例可能实际上已被复制。
在这种情况下,请实现copyWithZone
方法以确保新副本也获得渲染器。 (请注意,虽然我是Python开发人员和Objective-C可可开发人员,但我自己没有使用过PyObjC,所以我不能肯定你是否应该实现copyWithZone
或__copy__
)。
事实上,将copyWithZone
方法推入带有打印的类中将允许您判断是否正在调用该方法,以及这是渲染器似乎消失的原因。
编辑:根据您的反馈,我已将您的代码粘贴到一个空白的xcode python项目中(只是用其他东西代替gv.CoreRenderer,因为我没有这个),并且它通过一些小的修改工作正常。你如何实例化你的SceneView?
在我的情况下我:
SceneView.py
的新文件。我粘贴了你的代码。MainMenu.xib
文件,将NSOpenGLView框拖到窗口上。SceneView
import SceneView
的导入中添加了main.py
,以便在加载xib文件时该类可用awakeFromNib
中实施了SceneView.py
方法来处理设置self.renderer
。请注意,在程序执行期间,不会为nib对象调用__init__
和initWithFrame
...它们被视为“序列化”到nib文件中,因此已经实例化。我正在浏览一些细节,但这就是awakeFromNib存在的原因。__dict__
在drawRect_
调用中具有适当的值,等等。这是awakeFromNib函数:
def awakeFromNib(self):
print "Awake from nib"
self.renderer = gv.CoreRenderer()
所以,我猜测在你的对象被实例化和/或添加到视图中的某些地方只有一些交叉的线。您是使用Interface Builder作为对象,还是手动创建它并稍后将其添加到视图中?我很想知道你是从initWithFrame获取loggin输出的,这就是我问你如何创建SceneView的原因。
答案 1 :(得分:2)
即使它们没有被序列化,ObjectiveC-bridge也不支持python的__init __-构造函数。所以需要重载例如initWithFrame:用于自创视图。