2

我正在将 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 似乎知道枚举类型。

我正在努力做的是从 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 是错误的?

有人有一个工作的例子吗?

谢谢,弗兰克

4

2 回答 2

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");
于 2012-02-06T09:48:46.037 回答
0

哎呀。我对这个开枪了。尽管脚本有效,但我破坏了使用 qmetaobject 数据将枚举转换为字符串的能力。

而且似乎没有一种自动的方式来做到这一点。

问题是,我将枚举移出定义了使用枚举的属性的类。虽然 Q_ENUMS 和 Q_PROPERTY 可以编译,但如果我使用 QMetaProperty 来读取枚举,它就不起作用。返回的 QVariant 显示正确的数据类型“CEHalPinType::EHalPinType”,但它未能通过 isEnum() 测试并且 canConvert(QVariant::String) 也失败。这是因为当 qmetaobject 代码搜索枚举类型时,它只查找当前类及其派生类。它不搜索其他类。这就是为什么当枚举是也具有属性的类的成员时它起作用的原因。

正如其他地方所建议的那样,我的工作是创建我自己的已知枚举的 QMap,将字符串名称存储到 qmetaobject 映射。我使用模板化基类并使用 T::staticMetaObject 来获取元对象。

于 2012-02-09T10:46:20.490 回答