QCAD C++&Javascript混合调用
Javascript
绑定C++
类,与QML
&Javascript
和Qt C++
机制类似。
创建可供绑定的类
\support\examples\exampleplugin2\RExamplePlugin2.cpp
注意以下两点,绑定的前提。
Q_OBJECT
Q_DECLARE_METATYPE(MyClass*)
class MyClass : public QObject {
Q_OBJECT
public:
MyClass() : QObject(), i(0), d(0.0) {}
virtual int getInt() const {
return i;
}
virtual double getDouble() const {
return d;
}
virtual QString getString() const {
return s;
}
virtual void setInt(int v) {
i = v;
}
virtual void setDouble(int v) {
d = v;
}
virtual void setString(const QString& v) {
s = v;
}
void emitSignal() {
emit mySignal(i);
}
signals:
void mySignal(int code);
private:
int i;
double d;
QString s;
};
Q_DECLARE_METATYPE(MyClass*)
创建脚本类
/**
* Script binding for MyClass.
*/
class EcmaMyClass {
public:
static void initEcma(QScriptEngine& engine);
static QScriptValue createMyClass(QScriptContext* context, QScriptEngine* engine);
static QScriptValue myClassToString(QScriptContext *context, QScriptEngine *engine);
static MyClass* getSelfMyClass(const QString& fName, QScriptContext* context);
static QScriptValue getInt(QScriptContext* context, QScriptEngine* engine);
static QScriptValue getDouble(QScriptContext* context, QScriptEngine* engine);
static QScriptValue getString(QScriptContext* context, QScriptEngine* engine);
static QScriptValue setInt(QScriptContext* context, QScriptEngine* engine);
static QScriptValue setDouble(QScriptContext* context, QScriptEngine* engine);
static QScriptValue setString(QScriptContext* context, QScriptEngine* engine);
static QScriptValue emitSignal(QScriptContext* context, QScriptEngine* engine);
};
void EcmaMyClass::initEcma(QScriptEngine& engine) {
QScriptValue* proto = new QScriptValue(engine.newVariant(qVariantFromValue((MyClass*)0)));
// base class:
QScriptValue dpt = engine.defaultPrototype(qMetaTypeId<QObject*>());
proto->setPrototype(dpt);
REcmaHelper::registerFunction(&engine, proto, myClassToString, "toString");
engine.setDefaultPrototype(qMetaTypeId<MyClass*>(), *proto);
QScriptValue ctor = engine.newFunction(createMyClass, *proto, 0);
engine.globalObject().setProperty("MyClass", ctor, QScriptValue::SkipInEnumeration);
// register function getInt:
REcmaHelper::registerFunction(
&engine,
proto, // prototype
getInt, // reference to static function
"getInt"); // name in ECMAScript
REcmaHelper::registerFunction(&engine, proto, getDouble, "getDouble");
REcmaHelper::registerFunction(&engine, proto, getString, "getString");
REcmaHelper::registerFunction(&engine, proto, setInt, "setInt");
REcmaHelper::registerFunction(&engine, proto, setDouble, "setDouble");
REcmaHelper::registerFunction(&engine, proto, setString, "setString");
REcmaHelper::registerFunction(&engine, proto, emitSignal, "emitSignal");
}
/**
* Constructor for MyClass.
* Allows instantiation in ECMAScript as:
*
* var v = new MyClass();
*/
QScriptValue EcmaMyClass::createMyClass(QScriptContext* context, QScriptEngine* engine) {
if (context->thisObject().strictlyEquals(engine->globalObject())) {
return REcmaHelper::throwError(QString::fromLatin1("MyClass(): Did you forget to construct with 'new'?"), context);
}
// constructor without arguments:
if(context->argumentCount() == 0) {
MyClass* cppResult = new MyClass();
return engine->newQObject(context->thisObject(), cppResult);
}
else {
return REcmaHelper::throwError(QString::fromLatin1("MyClass(): no matching constructor found."), context);
}
}
/**
* Allows implicit converstion of MyClass objects to strings:
*
* var v = new MyClass();
* qDebug(v);
* // MyClass(0x12345678)
*/
QScriptValue EcmaMyClass::myClassToString(QScriptContext *context, QScriptEngine *engine) {
Q_UNUSED(engine)
MyClass* self = getSelfMyClass("toString", context);
if (self!=NULL) {
return QScriptValue(QString("MyClass(0x%1)").arg((unsigned long int)self, 0, 16));
}
return QScriptValue();
}
/**
* \return MyClass object from given script context. Helper function.
*/
MyClass* EcmaMyClass::getSelfMyClass(const QString& fName, QScriptContext* context) {
MyClass* self = REcmaHelper::scriptValueTo<MyClass >(context->thisObject());
if (self == NULL){
if (fName!="toString") {
REcmaHelper::throwError(QString("MyClass.%1(): This object is not a MyClass").arg(fName), context);
}
return NULL;
}
return self;
}
/**
* Binding for getInt.
*/
QScriptValue EcmaMyClass::getInt(QScriptContext* context, QScriptEngine* engine) {
MyClass* self = getSelfMyClass("getInt", context);
if (self!=NULL) {
int i = self->getInt();
return QScriptValue(engine, i);
}
return QScriptValue();
}
/**
* Binding for getDouble.
*/
QScriptValue EcmaMyClass::getDouble(QScriptContext* context, QScriptEngine* engine) {
MyClass* self = getSelfMyClass("getDouble", context);
if (self!=NULL) {
double d = self->getDouble();
return QScriptValue(engine, d);
}
return QScriptValue();
}
/**
* Binding for getString.
*/
QScriptValue EcmaMyClass::getString(QScriptContext* context, QScriptEngine* engine) {
MyClass* self = getSelfMyClass("getString", context);
if (self!=NULL) {
QString s = self->getString();
return QScriptValue(engine, s);
}
return QScriptValue();
}
/**
* Binding for setInt.
*/
QScriptValue EcmaMyClass::setInt(QScriptContext* context, QScriptEngine* engine) {
MyClass* self = getSelfMyClass("setInt", context);
if (self!=NULL) {
if (context->argumentCount()==1 && context->argument(0).isNumber()) {
int a0 = (int)context->argument(0).toNumber();
self->setInt(a0);
}
else {
return REcmaHelper::throwError("Wrong number/types of arguments for EcmaMyClass.setInt().", context);
}
}
return QScriptValue();
}
/**
* Binding for setDouble.
*/
QScriptValue EcmaMyClass::setDouble(QScriptContext* context, QScriptEngine* engine) {
MyClass* self = getSelfMyClass("setDouble", context);
if (self!=NULL) {
if (context->argumentCount()==1 && context->argument(0).isNumber()) {
double a0 = (double)context->argument(0).toNumber();
self->setDouble(a0);
}
else {
return REcmaHelper::throwError("Wrong number/types of arguments for EcmaMyClass.setDouble().", context);
}
}
return QScriptValue();
}
/**
* Binding for setString.
*/
QScriptValue EcmaMyClass::setString(QScriptContext* context, QScriptEngine* engine) {
MyClass* self = getSelfMyClass("setString", context);
if (self!=NULL) {
if (context->argumentCount()==1 && context->argument(0).isString()) {
QString a0 = context->argument(0).toString();
self->setString(a0);
}
else {
return REcmaHelper::throwError("Wrong number/types of arguments for EcmaMyClass.setString().", context);
}
}
return QScriptValue();
}
/**
* Binding for emitSignal.
*/
QScriptValue EcmaMyClass::emitSignal(QScriptContext* context, QScriptEngine* engine) {
MyClass* self = getSelfMyClass("emitSignal", context);
if (self!=NULL) {
if (context->argumentCount()==0) {
self->emitSignal();
}
else {
return REcmaHelper::throwError("Wrong number/types of arguments for EcmaMyClass.emitSignal().", context);
}
}
return QScriptValue();
}
QCAD
中的脚本绑定类
QCAD
为底层的C++类生成了可供脚本调用的脚本绑定类。
\src\scripting\ecmaapi\generated
原文链接:https://blog.csdn.net/mrbaolong/article/details/111885974