2012-02-04 33 views
2

我將QScript添加到我的Qt應用程序中。我已經添加了元數據並使用一些元數據函數通過C++代碼進行查詢。這工作正常 - 我可以導航對象層次並打印出值(包括枚舉)。QtScript plus枚舉

但是,我不能看到在Qt腳本中使用枚舉。

我有我的課......

class HalPin : public QObject 
{ 
Q_OBJECT 
public: 
enum EHalPinType 
{ 
    Bit = HAL_BIT, 
    Float = HAL_FLOAT, 
    S32 = HAL_S32, 
    U32 = HAL_U32 
}; 

enum EHalPinDirection 
{ 
    In = HAL_IN, 
    Out = HAL_OUT, 
    IO = HAL_IO 
}; 
Q_ENUMS(EHalPinType) 
Q_ENUMS(EHalPinDirection) 

public: 
explicit HalPin(QObject *parent = 0); 

signals: 

public slots: 

}; 

Q_DECLARE_METATYPE(HalPin::EHalPinType) 
Q_DECLARE_METATYPE(HalPin::EHalPinDirection) 
Q_DECLARE_METATYPE(HalPin*) 

我有了,是以枚舉作爲參數的方法的另一類...

class EmcHal : public QObject 
{ 
Q_OBJECT 
public: 
explicit EmcHal(QString moduleName, QObject *parent = 0); 

signals: 

public slots: 
QObject *createHalPin(HalPin::EHalPinType, HalPin::EHalPinDirection, QString name); 
}; 

這個類是在其他類暴露 - 對不起,我應該簡化這個例子。如果我寫了下面的JScript代碼,

var nextPagePin1 = Emc.hal.createHalPin(); 

我得到一個錯誤,我希望......

SyntaxError: too few arguments in call to createHalPin(); candidates are createHalPin(HalPin::EHalPinType,HalPin::EHalPinDirection,QString) 

因此,看來該enum類型已知qtscript。

我正在努力做的是從jscript設置枚舉參數。我試過很多種組合...

Bit 
EHalPinType.Bit 
HalPin.EHalPinType.Bit 

等等。

如果我嘗試使用整數,我得到...

TypeError: cannot call createHalPin(): argument 1 has unknown type `HalPin::EHalPinType' (register the type with qScriptRegisterMetaType()) 

這似乎意味着JScript不知道我的枚舉。

有什麼建議嗎?

我是否需要使用qRegisterMetaType或qScriptRegisterMetaType來訪問我的枚舉?該文件不建議我需要這樣做。我是否需要爲qScriptRegisterMetaType方法實現轉換器功能?

或者是我的語法只是錯誤的jscript?

有人有一個工作的例子嗎?

感謝, 弗蘭克

回答

2

回答我的問題...

好了,沒有那麼多的答案,爲什麼,而是一個 「咩,這個作品」 例如......

正如我上面提到的,我無法同時使用qt宏來獲取元數據和jscript中的枚舉。即使枚舉出現在qscript中(我在腳本調試器的瀏覽器中檢查過),它並沒有計算出正確的整數。我不得不爲這個枚舉添加一個QMetaObject。這給了我枚舉項和正確的整數值。

但這仍然給我未知類型的錯誤,所以我需要使用qScriptRegisterMetaType()註冊類型的轉換函數。

這是我用於1枚枚舉的類。它儘可能小,因爲我可以做到。我應該可以使用宏將其縮小一點,但由於qt moc的要求,可以對其進行宏觀化的限制。

#include <QObject> 
#include <QMetaType> 
#include <QScriptEngine> 

#include "hal.h" 


class CEHalPinType : public QObject 
{ 
Q_OBJECT 
public: 
    explicit CEHalPinType(QObject *parent = 0) : QObject(parent) {} 
    explicit CEHalPinType(const CEHalPinType &other) : QObject(other.parent()) {} 
    virtual ~CEHalPinType() {} 

    enum EHalPinType 
    { 
     Bit = HAL_BIT, 
     Float = HAL_FLOAT, 
     S32 = HAL_S32, 
     U32 = HAL_U32 
    }; 
    Q_ENUMS(EHalPinType) 

private: 
    static QScriptValue toScriptValue(QScriptEngine *engine, const EHalPinType &s) 
    { 
     return engine->newVariant((int)s); 
    } 

    static void fromScriptValue(const QScriptValue &obj, EHalPinType &s) 
    { 
     s = (EHalPinType)obj.toInt32(); 
    } 
    static QScriptValue qscriptConstructor(QScriptContext *context, QScriptEngine *engine) 
    { 
     return engine->newQObject(new CEHalPinType(context->argument(0).toQObject()), QScriptEngine::ScriptOwnership); 
    } 
public: 
    static void Init(const char *name, QScriptEngine *engine) 
    { 
     qScriptRegisterMetaType(engine, toScriptValue, fromScriptValue); 
     QScriptValue metaObject = engine->newQMetaObject(&staticMetaObject, engine->newFunction(qscriptConstructor)); 
     engine->globalObject().setProperty(name, metaObject); 
    } 
}; 

Q_DECLARE_METATYPE(CEHalPinType::EHalPinType) 

我的JScript的樣子......

var nextPagePin = Emc.hal.createHalPin(EHalPinType.Bit,EHalPinDirection.In,"nexis.NextPage"); 
0

哎呀。我跳過這一槍的槍。儘管腳本工作,我打破了使用qmetaobject數據將枚舉轉換爲字符串的能力。

而且似乎並沒有自動的方式。

問題是,我把枚舉移出使用枚舉的屬性被定義的類。雖然Q_ENUMS和Q_PROPERTY編譯,如果我使用QMetaProperty來讀取枚舉,它不起作用。返回的QVariant顯示正確的數據類型「CEHalPinType :: EHalPinType」,但isEnum()測試失敗,canConvert(QVariant :: String)失敗。這是因爲當qmetaobject代碼搜索枚舉類型時,它只會查找當前類及其派生類。它不搜索其他類。這就是爲什麼當枚舉是具有屬性的類的成員時它才起作用。

正如其他地方所建議的,我的工作是創建我自己的已知枚舉的QMap,將字符串名稱存儲到qmetaobject映射中。我使用了模板化的基類,並使用T :: staticMetaObject來獲取元對象。