QCAD
插件开发的三种模式
纯EcmaJavascript
模式
在qcad
程序安装目录下的scripts
文件夹下新建对应的文件夹和文件,文件夹、文件名以及类名三者保持一致。这种方式可以避免编译,暴露代码方便编辑修改。
scripts/MyTool/MyTool.js
MyTool.js
:实现一个MyTool
菜单,在主程序命令行窗口中输出Hello World
。要实现菜单功能,可以直接继承EAction
这个类。
include("scripts/EAction.js");
/*
* 构造函数
*/
function MyTool(guiAction) {
EAction.call(this, guiAction);
}
/*
* 继承EAction
*/
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);
//设置作为Misc的子菜单。命名规则,对象名+类型。
action.setWidgetNames(["MiscMenu"]);
};
C++
和EcmaJavascript
混合模式
将JS
代码作为动态链接库的资源,编译到动态链接库中。这种方式避免了暴露JS
代码,修改JS
代码后,需要重新编译插件动态链接库。
建立插件动态链接库项目
工程配置.pro
CONFIG += plugin
TARGET = example
include(../../../shared.pri)
TEMPLATE = lib
HEADERS = RExamplePlugin.h
SOURCES = RExamplePlugin.cpp
DESTDIR = $$PWD/../../../plugins
LIBS += -lqcadcore -lqcadgui -lqcadecmaapi
RESOURCES = scripts.qrc
源码文件
继承插件RPluginInterface
接口即可,一般默认即可。
RExamplePlugin.h
#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) {}
//初始化`js`扩展
virtual void initScriptExtensions(QScriptEngine&) {}
//插件信息
virtual RPluginInfo getPluginInfo();
//插件授权检查
virtual bool checkLicense() { return true; }
//插件国际化支持初始化
virtual void initTranslations(){}
};
RExamplePlugin.cpp
#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 < 0x050000
QT_BEGIN_NAMESPACE
Q_EXPORT_PLUGIN2(example, RExamplePlugin)
QT_END_NAMESPACE
#endif
scripts.qrc
在工程目录下,新建对应的文件夹、文件名以及其他资源。
scripts/MyTool/MyTool.js
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file alias="scripts/MyTool/MyTool.js">scripts/MyTool/MyTool.js</file>
</qresource>
</RCC>
纯C++
插件模式
相同的方式,建立插件工程。实现菜单功能需要继承RActionAdapter
。
#include <QDebug>
#include <QObject>
#include <QScriptEngine>
#include <QStringList>
#include "RActionAdapter.h"
#include "RDocumentInterface.h"
#include "RGuiAction.h"
#include "RMainWindow.h"
class MyTool : public RActionAdapter {
public:
MyTool(RGuiAction* guiAction) : RActionAdapter(guiAction) {}
static void factory(RGuiAction* guiAction) {
qDebug() << "MyTool::factory";
if (guiAction==NULL) {
qDebug("guiAction is NULL");
return;
}
RDocumentInterface* di = RMainWindow::getDocumentInterfaceStatic();
if (di==NULL) {
qDebug("di is NULL");
return;
}
di->setCurrentAction(new MyTool(guiAction));
}
virtual void beginEvent() {
qDebug() << "MyTool::beginEvent";
RMainWindowQt::handleUserMessage("Hello World");
}
};
修改postInit
初始化菜单。
void RExamplePlugin::postInit(InitStatus status) {
if (status!=RPluginInterface::AllDone) {
return;
}
RMainWindowQt* appWin = RMainWindowQt::getMainWindow();
RGuiAction* guiAction = new RGuiAction("&MyTool", appWin);
guiAction->setRequiresDocument(true);
guiAction->setGroupSortOrder(100000);
guiAction->setSortOrder(100);
QMenuBar* menuBar = appWin->menuBar();
QMenu* menu = menuBar->findChild<QMenu*>("MiscMenu");
guiAction->addToMenu(menu);
guiAction->setFactory(MyTool::factory);
}
参考
详情参考源码:qcad\\support\\examples\\exampleplugin
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END