【问题标题】:How to create a Cocoa library and use it in python如何创建一个 Cocoa 库并在 python 中使用它
【发布时间】:2010-07-03 13:36:46
【问题描述】:

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

我将能够弄清楚如何使用 NSWindow 和 NSOpenGLView 等类中的对象,然后将这些对象放入我自己的类中以进行游戏循环。

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

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

PyObjC 显然是“双向”的,那么它是如何完成的呢?

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

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

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

了解 Objective-C 的语法并不是什么大问题,我可以参考 Cocoa 文档来制作我需要的对象。

感谢您的帮助。将不胜感激。我厌倦了使用 pygame 和 pyglet 等损坏的库,使用特定于平台的 OS API 似乎是确保质量的最佳方法。

【问题讨论】:

  • 我不能使用 python 主循环吗?我必须在 NSApplication 上调用 run 方法,python 已准备好启动。然后我需要在我的 Objective-C 代码中调用一些 python 方法。幸运的是,我当前使用 pyglet 的代码使用了类似的东西,其中调用了 run 方法。这只是从 Objective-C 调用 python,这是令人讨厌的部分。
  • 在没有界面生成器的情况下,肯定有 Cocoa 的好教程吗?

标签: python objective-c cocoa pyobjc


【解决方案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 访问您的控制器单例。

【讨论】:

  • 感谢您提供的信息。这可能会变得有用。我一直在研究使用 PyObjC 在运行时加载动态库的可能性。我可能会先检查它是否有效,这可能是一个更简单、更优雅的解决方案。不过非常感谢。
  • 我似乎无法使用这些功能,所以我将不得不尝试您的建议。
  • 这些捆绑的东西之一怎么样?有一个 loadBundle 函数。
  • 我已经有一年多没有真正做到这一点了,所以很有可能 API 已经改进了。 “loadBundle”是指 Python 端 objc 模块中的 loadBundle 函数吗?这可用于将框架和其他包加载到 Objective-C 运行时,但在我的示例中,由于您的代码是运行 Python 代码的代码,因此您的 Objective-C 代码将已经在运行时中。因此,您需要使用 objc.lookUpClass 来访问您的 Objective-C 端控制器类。希望有帮助!
  • 我指的就是这个函数,没错。我遇到的问题是您的解决方案不会使 OSX 版本与其他所有版本兼容,因为我的程序应该是包含其他部分的 python 程序,而不是包含 python 的 Cocoa 程序。这意味着 OSX 版本将需要完全不同的结构。我打算再看看这个。谢谢您的帮助。非常感谢。 :D
猜你喜欢
  • 2020-07-30
  • 2019-03-30
  • 1970-01-01
  • 2015-03-06
  • 2021-03-21
  • 1970-01-01
  • 2015-06-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多