2013-04-30 13 views
6

Io corro in qualche strano comportamento in cui una proprietà può accedere direttamente attraverso la funzione 's QObjectproperty, ma non attraverso JavaScript:proprietà non definite solo quando si accede tramite lo script

#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" 

Che cosa sto facendo di sbagliato?

+0

Un esempio con più semplice l'accesso alle proprietà attraverso 'QScriptEngine' che espone anche il problema: http://paste.kde.org/741698/. – Mitch

risposta

1

Posso suggerire alcune cose.

Il nome oggetto deve essere impostato. Il nome degli oggetti all'interno dello script è impostato in questo modo.

setObjectName("Blah"); 

Non vedo dove stai un'istanza di un oggetto specifico e raccontare il motore di script su di esso:

ScriptEngine->globalObject().setProperty(objectName(), ScriptEngine->newQObject(myObject, QScriptEngine::AutoOwnership, QScriptEngine::ExcludeSuperClassContents)); 
+0

Quale oggetto? 'blah' è il nome della funzione che sto chiamando all'interno della sceneggiatura. [La documentazione] (http://qt-project.org/doc/qt-5.0/qtscript/qtscript-index.html#making-a-qobject-available-to-the-script-engine) dice che l'impostazione 'objectName 'non è necessario. Ho usato questo stesso codice fino ad ora con successo; ecco lo stesso esempio con un'altra funzione aggiunta che funziona su 'ItemStack' che funziona bene: http://paste.kde.org/735524/ – Mitch

+0

E con" stesso codice "intendo quello (come dimostrato in paste.kde. org link) l'accesso alle proprietà di altri oggetti ha funzionato bene. – Mitch

Problemi correlati