2

Qt アプリケーションに QScript を追加しています。既にメタデータを追加しており、いくつかのメタデータ関数を使用して 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 に答える