开发插件

插件开发

如何进行插件开发以及要将应用程序与 Toolkit 集成时需要什么?本文档介绍了一些我们经常被问到的有关插件开发的基本问题。

简介

本文档简要概述了与 Toolkit 插件开发相关的一些技术细节。开发插件时,您实际上是在宿主应用程序与插件中加载的各种应用和框架之间搭建一个连接桥梁。通过插件,可以抽象出各个应用程序之间的不同,从而可以使用 Python 和 QT 直接编写应用。

插件是一系列文件的集合,结构上与应用相似。它具有一个 engine.py 文件,而且该文件必须派生自 Tank 核心插件的基类。不同的插件根据内部的复杂性,重新执行此基类的各个方面。设计功能概括如下:

  • 基类公开各种 init 和 destroy 方法,这些方法将在启动过程的不同时间点执行。用户可改写这些方法来控制启动和关闭的执行。
  • 插件提供一个 commands 词典,其中包含应用注册的所有命令对象。创建菜单项时通常会访问此词典。
  • 当插件运行 QT 的方式不是默认的基类行为时,用户可改写用于显示用户界面对话框和窗口的方法。

插件需要处理的典型任务通常包括:

  • 菜单管理。插件启动时,待应用加载完毕后,插件需要创建其 Shotgun 菜单,并将各种应用添加到此菜单中。
  • 日志记录方法通常会被改写,以便向应用程序日志写入数据。
  • 用户界面方法通常会被改写,以确保 Toolkit 应用启动的窗口与底层的宿主应用程序窗口管理设置实现无缝集成。

Tank 核心平台使用 stgk.platform.start_engine() 命令启动插件。此命令会读取配置文件、启动插件并加载所有应用等。插件的目的在于,一旦启动,它将为各种应用提供一个统一的 Python/QT 界面。由于所有插件执行的是同一个基类,因此应用可调用插件上的方法来执行各种操作,例如创建用户界面。每个插件自己决定如何执行这些方法,以便它们能在宿主应用程序内部良好运行。

插件集成方法

根据宿主应用程序功能的不同,插件开发的复杂程度也会各异。本部分简要介绍目前我们在开发过程中遇到的几种不同的复杂程度。

宿主应用程序包含 QT、PyQt/PySide 和 Python

这是 Toolkit 的最佳设置,在支持 QT、Python 和 PySide 的宿主应用程序之上执行插件,操作起来非常简单。nuke 插件就是一个很好的例子。集成操作只是连接一些日志文件管理和编写代码设置 Shotgun 菜单而已。

宿主应用程序包含 QT 和 Python 但不包含 PySide/PyQt

这类应用程序包括诸如 MayaMotionBuilder 等,集成起来也相对轻松。由于宿主应用程序本身使用 QT 编写,并且包含 Python 解释器,因此我们可以编译一个 PySide 或 PyQt 版本,然后使用插件进行分发。随后,这个 PySide 会被添加到 Python 环境中,这样我们将可以使用 Python 访问 QT 对象。通常,在编译 PySide 时,必须使用与编译镜头应用程序时完全相同的编译器设置,以保证它能够正常工作。

宿主应用程序包含 Python

这类应用程序包括 HoudiniSoftimage。这些宿主应用程序具有非 QT 用户界面,但是包含 Python 解释器。这意味着,Python 代码可以在环境内执行,只是没有现有的 QT 事件循环运行。这种情况下,需要在插件中包含 QT 和 PySide,并且必须将 QT 消息泵(事件)循环与用户界面中的主事件循环相连。宿主应用程序有时包含专门用于此用途的特殊方法。如果不包含,则必须做好安排,例如通过 on-idle 调用方法,让 QT 事件循环定期运行。

宿主应用程序不包含 Python 但您可以编写插件

这类应用程序包括 Photoshop。程序没有 Python 脚本编写功能,但是可以创建 C++ 插件。在这种情况下,采取的策略通常是创建一个插件,该插件包含一个 IPC 层,并会在启动时以单独的进程启动 QT 和 Python。等到辅助进程开始运行时,将使用 IPC 层来回发送命令。这类宿主应用程序往往意味着我们需要进行大量工作才能获得可以使用的插件解决方案。

宿主应用程序完全不提供脚本编写功能

如果宿主应用程序完全不能通过编程方式访问,将无法为它创建插件。

QT 窗口父子关系设置

窗口父子关系设置通常是一个需要特别注意的方面。通常,PySide 窗口在控件层次结构中并不会自然具有父窗口,这需要明确指出。窗口父子关系设置对于提供一致的体验来说非常重要,如果不实现这一点,Toolkit 应用窗口可能会显示在主窗口后面,看上去会非常混乱。

宿主应用程序期望具备的特性列表

Toolkit 插件可利用宿主应用程序的以下特性 (Trait)。支持的特性越多,插件的体验越好!

  • 内置 Python 解释器、QT 和 PySide!

  • 可在应用程序启动/初始化时运行代码。

  • 可在两种情况下访问和自动运行代码:一个是应用程序正常运行时,另一个是用户界面已完全初始化时。

  • 提供 API 命令来打包文件系统交互操作:“打开”(Open)、“保存”(Save)、“另存为”(Save As)、“Add Refernece”等。

  • 提供 API 命令来添加用户界面元素

    • 向应用中添加自定义 QT 控件作为面板(最好是通过捆绑的 PySide)
    • 添加自定义菜单/上下文菜单项
    • 在基于节点的程序包中添加自定义节点(通过简单的方法滚动自己的用户界面进行交互)
    • 提供自检功能发现选定的项/节点等对象
  • 灵活的事件系统

    • “有意义”的事件可以触发自定义代码
  • 支持异步运行用户界面

    • 例如,当某个自定义菜单项被触发时弹出一个不锁定界面的对话框
    • 为顶层窗口提供句柄,以便可以正确设置自定义用户界面窗口的父子关系
关注

0 评论

登录写评论。