2012-02-04 6 views
2

Я добавляю QScript в мое приложение Qt. Я уже добавил метаданные и использовал некоторые функции метаданных для опроса через код на C++. Это отлично работает - я могу перемещаться по иерархии объектов и распечатывать значения (включая перечисления).QtScript plus enums

Но, я не вижу, чтобы получить перечисления, работающие в скрипте 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) 

Таким образом, оказывается, что типы перечислений известны QtScript.

То, что я пытаюсь сделать, это установить аргументы enum из 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?

У кого-нибудь есть рабочий пример?

Спасибо, Frank

ответ

2

Для того, чтобы ответить на мой собственный вопрос ...

Ну, не столько ответ, почему, но "Мех, это работает" пример ...

Как я уже упоминал выше, я не смог получить перечисления, работающие как в метаданных, так и в jscript, используя макросы qt. Хотя перечисление появилось в 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 для получения метаобъекта.