Tôi đang chạy vào một số hành vi kỳ lạ, nơi một tài sản có thể được truy cập trực tiếp thông qua property
chức năng QObject
's, nhưng không thông qua JavaScript:Thuộc tính chỉ undefined khi truy cập thông qua kịch bản
#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"
Tôi đang làm gì sai?
Một ví dụ với truy cập đơn giản để các thuộc tính thông qua 'QScriptEngine' đó cũng thể hiện sự vấn đề: http://paste.kde.org/741698/. – Mitch