Properties undefined when accessed through script
-
I'm encountering a problem that I've been trying to solve for a while: http://stackoverflow.com/questions/16310311/properties-undefined-only-when-accessed-through-script
A property can be accessed directly through QObject's property function, but not through JS:
@#include <QApplication>
#include <QDebug>
#include <QScriptEngine>
#include <QStringList>class Item : public QObject
{
Q_OBJECT
public:
Q_PROPERTY(int typeId READ typeId)
Q_PROPERTY(int usesLeft READ usesLeft)Item() : mTypeId(0), mUsesLeft(-1) { } Item(int typeId) : mTypeId(typeId) { if (typeId != 0) { mUsesLeft = 5; } } Item(const Item &item) : QObject(0) { *this = item; } ~Item() { } Item& operator=(const Item& rhs) { mTypeId = rhs.mTypeId; mUsesLeft = rhs.mUsesLeft; return *this; } int typeId() const { return mTypeId; } int usesLeft() const { return mUsesLeft; } void setUsesLeft(int usesLeft) { mUsesLeft = usesLeft; } friend QDataStream &operator<<(QDataStream &out, const Item &item); friend QDataStream &operator>>(QDataStream &in, Item &item); friend QDebug operator<<(QDebug debug, const Item &item);
private:
int mTypeId;
int mUsesLeft;
};QDataStream &operator<<(QDataStream &out, const Item &item)
{
out << item.typeId()
<< item.usesLeft();
return out;
}QDataStream &operator>>(QDataStream &in, Item &item)
{
in >> item.mTypeId
>> item.mUsesLeft;
return in;
}QDebug operator<<(QDebug debug, const Item &item)
{
debug.nospace() << "(Item typeId=" << item.typeId()
<< ", usesLeft=" << item.usesLeft();
return debug.space();
}Q_DECLARE_METATYPE(Item)
class ItemStack : public QObject
{
Q_OBJECT
public:
Q_PROPERTY(Item *item READ item)
Q_PROPERTY(int size READ size)ItemStack() : mSize(0) { } ItemStack(const ItemStack &rhs) : QObject() { *this = rhs; } ItemStack(const Item &item, int size) : mItem(item), mSize(size) { } ~ItemStack() { } ItemStack& operator=(const ItemStack& rhs) { if(this == &rhs) return *this; mItem = rhs.mItem; mSize = rhs.mSize; return *this; } Item* item() { return &mItem; } const Item *item() const { return &mItem; } int size() const { return mSize; } friend QDataStream &operator<<(QDataStream &out, const ItemStack &itemStack); friend QDataStream &operator>>(QDataStream &in, ItemStack &itemStack); friend QDebug operator<<(QDebug debug, const ItemStack &itemStack);
private:
Item mItem;
int mSize;
};QDataStream &operator<<(QDataStream &out, const ItemStack &itemStack)
{
out << *itemStack.item()
<< itemStack.size();
return out;
}QDataStream &operator>>(QDataStream &in, ItemStack &itemStack)
{
in >> itemStack.mItem
>> itemStack.mSize;
return in;
}QDebug operator<<(QDebug debug, const ItemStack &itemStack)
{
debug.nospace() << "(ItemStack item=" << *itemStack.item()
<< ", size=" << itemStack.size()
<< ")";
return debug.space();
}Q_DECLARE_METATYPE(ItemStack)
class GunEntity : public QObject
{
Q_OBJECT
public:
Q_PROPERTY(ItemStack roundsLoaded READ roundsLoaded)GunEntity() : mRoundsLoaded(Item(1), 7) {} ItemStack roundsLoaded() { return mRoundsLoaded; }
private:
ItemStack mRoundsLoaded;
};int main(int argc, char *argv[])
{
QApplication a(argc, argv);// Accessing directly through properties. GunEntity ge; qDebug() << "Can convert ge.roundsLoaded to ItemStack?" << ge.property("roundsLoaded").canConvert<ItemStack>(); ItemStack is = ge.property("roundsLoaded").value<ItemStack>(); qDebug() << is; qDebug() << "Can convert is.item to Item?" << is.property("item").canConvert<Item*>(); qDebug() << *is.property("item").value<Item*>(); qDebug() << "Can convert is.size to int?" << is.property("size").canConvert<int>(); qDebug() << is.property("size").toInt(); // Accessing through QScriptEngine. QScriptEngine se; se.evaluate("function blah(gun) { print(gun.roundsLoaded); print(gun.roundsLoaded.item); print(gun.roundsLoaded.size); }"); if (se.hasUncaughtException()) { qDebug() << se.uncaughtException().toString() << ":" << se.uncaughtExceptionLineNumber() << se.uncaughtExceptionBacktrace(); } QScriptValueList args; args << se.newQObject(&ge); QScriptValue ret = se.globalObject().property("blah").call(se.globalObject(), args); if (se.hasUncaughtException()) { qDebug() << se.uncaughtException().toString() << ":" << se.uncaughtExceptionLineNumber() << se.uncaughtExceptionBacktrace(); } return 0;
}
#include "main.moc"@
Any suggestions are welcomed. :)