views:

86

answers:

2

Hello everyone,

I try to find out how to use complex numbers in QtScripts such that slots defined with complex arguments can be called from a QtScript. Also basic algebra (+,-,exp, ... ) of complex-numbers should be accessible to the user from the script.

Just for illustration want I want to call is:

#include<complex>
typedef complex<double> Complex;

class MyCppClass : public QObject
{
Q_OBJECT
public:
  ...
public slots:
void mySignal(Complex rCValue); !! <<== should be callable from QtScript
  ...
}

Any ideas? Thx!

A: 

I think you must implement complex algebra in QtScript (something like http://examples.oreilly.com/9781565923928/text/8-6.txt) and then modify mySignal to accept an object like this.

mbq
Ok, may be that's the way to go. However, as far as I can see there is no such thing like operator overloading in ECMA-262 aka Javascript. I was hoping that the using a QScriptable inheriting prototype wrapper could overcome this ... but it seems I'm out of luck (no +,-,* just add,minus,multiply). Can anyone confirm this?
FFox
Right, I haven't thought about it... Sadly the lack of op overloading seems common to other macro languages. Maybe your problem is easy enough to write your own interpreter?
mbq
A: 

It's not the final answer ... since as indicated above the operators +,- and * cannot be used for Complex quantities on the javascript side. But for those interested I'd like to share the following code pieces, which allow to trigger slots with complex arguments.

test.h:

#include <QtCore>
#include <QtScript>
#include <complex>
#include <iostream>
using namespace std;
typedef complex<double> Complex;
Q_DECLARE_METATYPE(Complex)

class TestClass : public QObject
{
Q_OBJECT    
public:
    TestClass() : QObject() {};
public slots:   
    void TestOutput(Complex rValue);
};

test.cpp:

#include "test.h"
void TestClass::TestOutput(Complex rValue)
{
    cout << "received value "<< rValue << endl;
}

main.cpp:

#include "test.h"
QScriptValue toScriptValue(QScriptEngine *eng, const Complex& rValue)
{
    QScriptValue obj = eng->newObject();
    obj.setProperty("re",real(rValue));
    obj.setProperty("im",imag(rValue));
    return obj;
}

void fromScriptValue(const QScriptValue &obj, Complex& rValue)
{
    double re=obj.property("re").toNumber();
    double im=obj.property("im").toNumber();
    rValue=Complex(re,im);
}

QScriptValue constructComplex(QScriptContext *context, QScriptEngine *engine)
{
    Complex complex=Complex(2,1);
    return engine->toScriptValue(complex);
}

int main(int argc, char *argv[])
{
    QCoreApplication app(argc, argv);
    QScriptEngine eng;
    // register our custom type
    qScriptRegisterMetaType<Complex>(&eng, toScriptValue, fromScriptValue);

    TestClass *test=new TestClass;
    QObject *someObject = (QObject*)test;
    QScriptValue objectValue = eng.newQObject(someObject);
    eng.globalObject().setProperty("myObject", objectValue);

    QScriptValue val = eng.evaluate("function Complex(real, imaginary) { this.re = real; this.im = imaginary;}; cadd = function (a, b) {return new Complex(a.re + b.re, a.im + b.im);};");
    val = eng.evaluate("my_complex=new Complex(8,1); my_comp=new Complex(2,9);     my_c=cadd(my_comp,my_complex);");
    cout << "script"<< val.toString().toStdString() << endl;
    Complex cval = qscriptvalue_cast<Complex>(val);
    cout << "qscriptvalue_cast : "<< cval << endl;

    val = eng.evaluate("myObject.TestOutput(my_c)");

    return 0;
}
FFox