Script prototype for value
-
wrote on 27 Mar 2011, 16:59 last edited by
Hi,
I'm trying to pass my custom class, not based on QObject, to a script. I created a prototype that inherits from QScriptable, implemented all the properties and functions (as slots) I wanted, called Q_DECLARE_METATYPE and registered it to my QScriptEngine:
@PlanetPrototype planetPrototype = new PlanetPrototype;
QScriptValue planetProto = scriptEngine->newQObject(planetPrototype);
scriptEngine->setDefaultPrototype(qMetaTypeId<Planet>(), planetProto);@So how do I now convert a Planet* to QScriptValue? If I do either of:
@engine->toScriptValue<Planet*>(myplanet);
engine->toObject(engine->toScriptValue<Planet*>(myplanet)@
the result is undefined in JavaScript.Regards,
Marcin Jakubowski -
wrote on 27 Mar 2011, 19:34 last edited by
How does your code compare with the following?
@
#include <QtCore>
#include <QtScript/QtScript>class Data
{
public:
Data() : _id("no-data"), _num(0) {}
Data(const QString &id, int num):
_id(id), _num(num)
{}QString id() const { return _id; } void setId(const QString& id) { _id = id; } int num() const { return _num; } void setNum(int num) { _num = num; }
private:
QString _id;
int _num;
};Q_DECLARE_METATYPE(Data*)
class DataPrototype : public QObject, public QScriptable
{
Q_OBJECT
Q_PROPERTY(QString id READ id)
Q_PROPERTY(int num READ num)
public:
DataPrototype(QObject *parent = 0) : QObject(parent) {}QString id() const { Data *item = qscriptvalue_cast<Data*>(thisObject()); if (item) return item->id(); return "none"; } int num() const { Data *item = qscriptvalue_cast<Data*>(thisObject()); if (item) return item->num(); return 1; }
};
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);QScriptEngine engine; DataPrototype dataPrototype; QScriptValue dataProto = engine.newQObject(&dataPrototype); engine.setDefaultPrototype(qMetaTypeId<Data*>(), dataProto); Data d("test", 7); engine.globalObject().setProperty("d", engine.toScriptValue(&d)); QScriptValue result = engine.evaluate("d.id + ': ' + d.num"); qDebug() << result.toString(); // displays "test: 7" QTimer::singleShot(1000, &app, SLOT(quit())); return app.exec();
}
#include "main.moc"
@ -
wrote on 27 Mar 2011, 19:52 last edited by
Seems correct to me, pretty much the same as yours:
@
Q_DECLARE_METATYPE(Planet*)
class PlanetPrototype : public QObject, public QScriptable
{
Q_OBJECTQ_PROPERTY(QString id READ id) Q_PROPERTY(QString name READ name) Q_PROPERTY(int iCoords READ iCoords) Q_PROPERTY(QString coords READ coords)
public:
PlanetPrototype(QObject *parent = 0);QString id() const; QString name() const; int iCoords() const; QString coords() const;
public slots:
int info(int id);private:
Planet* thisPlanet() const;
};// somewhere else
PlanetPrototype planetPrototype = new PlanetPrototype;
QScriptValue planetProto = scriptEngine->newQObject(planetPrototype);
qDebug() << qMetaTypeId<Planet>(); // is ok, returns 277Planet *p = new Planet("test planet", "1000", PlanetCoords(1, 2, 3, 4, 5));
scriptEngine->globalObject().setProperty("myplanet", scriptEngine->toScriptValue(p));scriptEngine->globalObject().setProperty("myplanet", scriptEngine->toScriptValue(p));
QScriptValue result = scriptEngine->evaluate("'givf object plx:' + myplanet");
qDebug() << result.toString(); // gives undefined@
-
wrote on 27 Mar 2011, 19:56 last edited by
Oh the stupidity.
@
QScriptValue result = scriptEngine->evaluate("'givf object plx:' + myplanet + ' - ' + myplanet.name");
qDebug() << result.toString(); // givf object plx:undefined - test planet
@Although it seems strange that it says undefined even though it is not... I'm not an ECMAScript expert but I thought it should give me an Object.
-
wrote on 27 Mar 2011, 21:57 last edited by
It says undefined because the toString() function is undefined for the prototype set for Planet*. If the setDefaultPrototype() on Planet* is not used, it would probably result in "givf object plx:QVariant(Planet*) - undefined". Define a toString() slot for the PlanetPrototype class and see how the result changes.
-
wrote on 27 Mar 2011, 22:00 last edited by
Indeed, changes accordingly. Makes sense, thank you very much!
2/6