PDA

View Full Version : How to add class member function in QScriptEngine



Sacha_D
19th April 2013, 13:24
I need to add class member function in QScriptEngine.
How to do this correctly?

.h file

class MainWindow : public QMainWindow
{
Q_OBJECT
private:
QScriptEngine scriptEngine;

void setupFirst();
public:
QScriptValue appendDevice(QScriptContext *ctx, QScriptEngine *eng);
};


.cpp file

void MainWindow::setupFirst() {

this->scriptEngine.globalObject().setProperty("appendDevice",
this->scriptEngine.newFunction(
boost::bind(&MainWindow::appendDevice, this, _1, _2),
3)
); // How to do this correctly?
}

QScriptValue MainWindow::appendDevice(QScriptContext *ctx, QScriptEngine *eng){

QString functionDescription = tr("Function format ") + "bool appendDevice(QString name, int address, const QString portName," +
"const int rate = 115200," +
"const QString config = \"\");";
if (ctx->argumentCount() < 3){
return ctx->throwError(QScriptContext::SyntaxError, tr("Unsufficient args count. ") + functionDescription);
}
QString name;
int address;
QString portName;
if (ctx->argumentCount() >= 3){
if (ctx->argument(0).isString()) {
name = ctx->argument(0).toString();
}
else {
return ctx->throwError(QScriptContext::TypeError, tr("Arg [0] (Device name) must be a string. ") + functionDescription);
}

if (ctx->argument(1).isNumber()) {
address = ctx->argument(1).toInt32();
}
else {
throw ctx->throwError(QScriptContext::TypeError, tr("Arg [1] (Device address) must be a number. ") + functionDescription);
}

if (ctx->argument(2).isString()) {
portName = ctx->argument(2).toString();
}
else {
throw ctx->throwError(QScriptContext::TypeError, tr("Arg [2] (Device port) must be a string. ") + functionDescription);
}
}
int rate = QExtSerialPortAux::rateToInt(QExtSerialPortAux::de faultRate);
QString config;

if (ctx->argumentCount() >= 4){
if (ctx->argument(3).isNumber()) {
rate = ctx->argument(3).toInt32();
}
else {
throw ctx->throwError(QScriptContext::TypeError, tr("Arg [3] (Port baud rate) must be a number. ") + functionDescription);
}
}
if (ctx->argumentCount() >= 5){
if (ctx->argument(4).isString()) {
config = ctx->argument(4).toString();
}
else {
throw ctx->throwError(QScriptContext::TypeError, tr("Arg [4] (Device config) must be a string. ") + functionDescription);
}
}

return appendDeviceFromScript(name, address, portName, rate, config);
}

Thank you for your replies.

anda_skoa
23rd April 2013, 13:59
My suggestion is to create a QObject and QScriptable subclass that serves as your script API, put all function as public slots into it and then export that object to the script engine using newQObject().

In your case, where you take a set of values from the script, I would even consider a small class/struct that can hold those values, make it known to the scriptengine using qScriptRegisterMetaType (see the example in its documentation) and then use this as the only parameter for the append function.

The script would then look more like this


var device = new Device();
device.name = "device1"
device.address = 1

// ..

program.appendDevice(device)


Cheers,
_

Sacha_D
23rd April 2013, 16:10
Thank you.