创建 QCAD 插件
QCAD 插件可用于以 C 或 C++ 实现的功能来扩展 QCAD。
实现 RPluginInterface
Section titled “实现 RPluginInterface”所有 QCAD 插件都必须直接或间接派生自 QObject 和抽象基类 RPluginInterface。
文件 RExamplePlugin.h
Section titled “文件 RExamplePlugin.h”对于我们第一个极简的示例插件,我们将 RPluginInterface 的大多数方法的空实现或极简实现直接添加到头文件中。可以复制头文件的此初始结构,以获得可加载到 QCAD 中的第一个可用插件。
#include <QObject>#include <QScriptEngine>
#include "RPluginInterface.h"
class RExamplePlugin : public QObject, public RPluginInterface{ Q_OBJECT Q_INTERFACES(RPluginInterface)#if QT_VERSION >= 0x050000 Q_PLUGIN_METADATA(IID "org.qcad.exampleplugin")#endif
public: virtual bool init() { return true; } virtual void uninit(bool) {} virtual void postInit(InitStatus status) {} virtual void initScriptExtensions(QScriptEngine& engine) {} virtual RPluginInfo getPluginInfo(); virtual bool checkLicense() { return true; }};文件 RExamplePlugin.cpp
Section titled “文件 RExamplePlugin.cpp”对于 getPluginInfo 方法,我们向 cpp 文件添加一个简单的实现,以便在 QCAD 的关于对话框中看到一些内容。
#include "RExamplePlugin.h"
RPluginInfo RExamplePlugin::getPluginInfo() { RPluginInfo ret; ret.set("Version", "1.0"); ret.set("ID", "EXAMPLE"); ret.set("Name", "Example Plugin"); ret.set("License", "GPLv3"); ret.set("URL", "http://qcad.org"); return ret;}
#if QT_VERSION < 0x050000QT_BEGIN_NAMESPACEQ_EXPORT_PLUGIN2(example, RExamplePlugin)QT_END_NAMESPACE#endif文件 exampleplugin.pro
Section titled “文件 exampleplugin.pro”要编译我们的插件,我们还需要一个 Qt 项目文件,可以使用 Qt qmake 将其转换为 Makefile。
CONFIG += pluginTARGET = exampleinclude(../../../shared.pri)
TEMPLATE = libHEADERS = RExamplePlugin.hSOURCES = RExamplePlugin.cppDESTDIR = ../../../pluginsLIBS += -lqcadcore -lqcadgui -lqcadecmaapi第 3 行的 include 应指向 QCAD 源代码安装的 shared.pri 文件(例如 qcad/shared.pri)。作为 DESTDIR,您可能希望选择可用 QCAD 安装的 plugins 文件夹,以便插件编译在正确的位置,从该位置 QCAD 也可以加载它。
可以使用这三个文件编译您的插件,创建文件 qcad/plugins/qcadexample.dll 或 libqcadexample.so 或 libqcadexample.dylib。
注意:如果您运行以调试模式编译的 QCAD 二进制文件,则插件也必须以调试模式编译。如果您以发布模式运行 QCAD,则插件也必须以发布模式编译。
要以调试模式编译插件,请运行:
Linux / macOS:
qmakemake debugWindows:
qmakenmake debug要以发布模式编译,请改为运行 make release 或 nmake release。
显然,该插件尚不会执行任何有用的操作,但您应该能够在 QCAD 关于对话框中看到您的插件:
如果看不到您的插件,请在启动 QCAD 时检查终端中的错误。您也可能在关于对话框中看到错误消息。
将脚本作为资源编译到插件中
Section titled “将脚本作为资源编译到插件中”QCAD 插件可用于将脚本和其他资源(ui 文件、图标等)的集合编译到插件中。这样做的优点是可以将多个 ECMAScript 文件的代码捆绑在单个已编译的二进制文件中。插件的加载往往比磁盘上的单个文件更快,并且占用的磁盘空间更少。
文件 scripts/MyTool/MyTool.js
Section titled “文件 scripts/MyTool/MyTool.js”假设有一个文件夹 scripts/MyTool,其中有一个文件 MyTool.js,包含一个用 ECMAScript 实现的 QCAD 工具。该工具将自身添加到杂项菜单的顶部,并在触发时输出 “Hello World”。
include("scripts/EAction.js");
function MyTool(guiAction) { EAction.call(this, guiAction);}
MyTool.prototype = new EAction();
MyTool.prototype.beginEvent = function() { EAction.prototype.beginEvent.call(this);
EAction.handleUserMessage("Hello World");
this.terminate();};
MyTool.init = function(basePath) { var action = new RGuiAction("&MyTool", RMainWindowQt.getMainWindow()); action.setRequiresDocument(true); action.setScriptFile(basePath + "/MyTool.js"); action.setGroupSortOrder(0); action.setSortOrder(0); action.setWidgetNames(["MiscMenu"]);};文件 scripts.qrc
Section titled “文件 scripts.qrc”要将此脚本工具编译到我们的 C++ 插件中,我们需要创建一个 Qt 资源文件,将 qmake 指向我们要编译到插件中的文件:
<!DOCTYPE RCC><RCC version="1.0"> <qresource> <file alias="scripts/MyTool/MyTool.js">scripts/MyTool/MyTool.js</file> </qresource></RCC>qrc 文件列出了资源在 Qt 资源系统中可用的路径(alias=“scripts/MyTool/MyTool.js”)以及可以在磁盘上找到该文件的实际路径(仅用于编译)。上述示例意味着磁盘上 scripts/MyTool/MyTool.js 下有一个文件,将被编译到插件中。插件一加载,该文件就可以在路径 “:/scripts/MyTool/MyTool.js” 下使用。QCAD 会自动在该路径下找到该工具,因为它会扫描 “scripts” 文件夹以及 “:/scripts” 来查找脚本。
我们还需要通过添加以下行将 qrc 文件添加到项目文件(exampleplugin.pro)中:
RESOURCES = scripts.qrc编辑文件 exampleplugin.pro 后,再次运行 qmake 和 make 并加载插件。现在,QCAD 中杂项菜单的顶部应该有一个 “MyTool” 菜单项。
您可以在以下位置找到此示例插件的完整源代码:
https://github.com/qcad/qcad/tree/master/support/examples/exampleplugin
- 如果您的插件可以编译但无法被 QCAD 加载,请确保使用与 QCAD 相同的 Qt 版本(请参阅 帮助 > 关于 QCAD)。请确保如果 QCAD 以发布模式运行,您的插件也以发布模式编译。
- 从终端或命令行启动 QCAD,并检查控制台输出中的错误消息。在您的插件中输出消息以确认它正在加载。例如在您的 init 函数中。
- 检查关于对话框(帮助 > 关于 QCAD > 插件)中的错误消息。