QtScript плюс перечисления - PullRequest
       14

QtScript плюс перечисления

2 голосов
/ 04 февраля 2012

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

Но я не вижу, чтобы перечисления работали в сценарии 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 ]

2 голосов
/ 06 февраля 2012

Чтобы ответить на мой собственный вопрос ...

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

Как я уже говорил выше,Я не смог заставить работать перечисления в метаданных и jscript одновременно с использованием макросов qt.Несмотря на то, что перечисление появилось в qscript (я проверил в браузере отладчика сценариев), оно не дало правильное целое число.

Мне пришлось добавить QMetaObject для перечисления.Это дало мне элементы enum и правильные целочисленные значения.

Но это все же дало мне неизвестную ошибку типа, поэтому мне нужно было использовать 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 голосов
/ 09 февраля 2012

К сожалению. Я бросил пистолет на этом. Хотя сценарии работали, я отказался от возможности преобразовывать перечисления в строки с использованием данных qmetaobject.

И, похоже, не существует автоматического способа сделать это.

Проблема в том, что я переместил перечисления из класса, где были определены свойства, которые использовали перечисления. Хотя Q_ENUMS и Q_PROPERTY компилируются, если я использую QMetaProperty для чтения перечисления, это не работает. Возвращаемый QVariant показывает правильный тип данных "CEHalPinType :: EHalPinType", но он не проходит тест isEnum (), а canConvert (QVariant :: String) тоже не выполняется. Это потому, что когда код qmetaobject отправляется на поиск типа enum, он ищет только текущий класс и его производные классы. Он не ищет другие классы. Именно поэтому он работал, когда enum был членом класса, который также имел свойства.

Моя работа вокруг, как предлагалось в другом месте, заключалась в том, чтобы создать мой собственный QMap известных перечислений, сохраняя имя строки в отображении qmetaobject. Я использовал шаблонный базовый класс и использовал T :: staticMetaObject, чтобы получить мета-объект.

...