如何创建一个Cocoa库并在python中使用它

时间:2010-07-03 13:36:46

标签: python objective-c cocoa pyobjc

我一直在制作游戏,而我使用的python库很糟糕(Pyglet)。我想尝试将Cocoa用于OSX版本。

我将能够找出使用像NSWindow和NSOpenGLView这样的类中的对象,然后将这些对象放在我自己的类中用于游戏循环。

我不知道如何使用PyObjC加载我可以创建的动态Objective-C库,然后使用我将在python中创建的类来设置我认为可以被NSTimer循环的游戏。

但是,loop方法还需要从许多python类中的一个调用python方法。我的游戏包含许多python类,用于游戏的不同部分(Mapmaker,GameSession,AnacondaGame等)。游戏循环需要在任何这些类中调用循环方法,具体取决于当前部分并传递偶数信息。

PyObjC显然是“双向的”,那怎么办呢?

或者我可以创建两个由python调用的方法,并在中间添加python代码,其中循环由python控制。

PyObjC网站上的“文档”似乎只解释了如何在python中使用Cocoa而不是其他内容。

我不能做的是使用界面构建器创建一个固定的GUI,因为库需要根据我的类的初始化方法的python输入创建窗口。

了解Objective-C的语法并不是一个大问题,我可以转而使用Cocoa文档来制作我需要的对象。

感谢您的帮助。非常感谢。我厌倦了使用像pygame和pyglet这样的破坏库,使用特定于平台的OS API似乎是确保质量的最佳方法。

1 个答案:

答案 0 :(得分:1)

PyObjC将Python桥接到Objective-C运行时,因此如果您在Python中创建NSObject子类,则可以从在同一进程中运行的Objective-C代码访问它们。这意味着您需要将所有Python功能封装在可以通过网桥访问的NSObject的子类中。

我这样做的方法是在Objective-C端有一个单独的控制器类,它有一个类似-(void)pythonReady:(PythonClass *)pythonObject的方法,并且还处理Python代码的加载(这确保了控制器类在加载Python代码时存在)。然后,在Python代码中,在创建PythonClass的实例之后,可以在控制器单例上调用pythonReady:。然后,在Objective-C方面的pythonReady:中,您可以在pythonObject上调用所需的任何方法,这将在Python端运行代码。

要从控制器类加载Python代码,您可以执行以下操作:

#import <Python/Python.h>

@implementation PythonController (Loading)
- (void)loadPython {
    NSString *pathToScript = @"/some/path/to/script.py";
    setenv("PYTHONPATH", [@"/some/path/to/" UTF8String], 1);
    Py_SetProgramName("/usr/bin/python");
    Py_Initialize();
    FILE *pyScript = fopen([pathToScript UTF8String], "r");
    int result = PyRun_SimpleFile(pyScript, [[pathToScript lastPathComponent] UTF8String]);
    if (result != 0) { NSLog(@"Loading Python Failed!"); }
}
@end

基本上,我们只是使用Python C API在当前进程中运行脚本。脚本本身在当前进程中启动到运行时的桥接,然后您可以使用Cocoa API访问控制器单例。