2017-04-23 8 views
1

私は、その内容がオペレーティングシステムに基づいて変化する列挙型を持っています。だから、私のような何かをしたい:QMetaEnum:定義を使用するには?

QMetaEnum::fromType<AudioRenderer>(); 

をし、それで物事を実行します。

#ifdef _WIN32 
    enum AudioRenderer 
    { 
     Null, 
     OpenAL, 
     XAudio2 
    }; 
#endif 
#ifdef __LINUX 
    enum AudioRenderer 
    { 
     Null, 
     OpenAL, 
     ALSA 
    }; 
#endif 
Q_ENUM(AudioRenderer) 

その後、私が呼び出されます。この場合、enumを文字列に変換して設定ファイルに書き込みます。

ただし、これを実行しようとするたびに、メタノームの内部mobjはnullと表示されます。私は(私は通常、それをダウンロードしたが、あなたはまだ含まれ、ヘッダーに続くことができる)Qtのコードの一部をステップ実行することができます

+  metaEnum {mobj=0x0000000000000000 <NULL> handle=0 } QMetaEnum 

を(Visual Studioのデバッガから撮影)。

template<typename T> static QMetaEnum fromType() { 
    Q_STATIC_ASSERT_X(QtPrivate::IsQEnumHelper<T>::Value, 
         "QMetaEnum::fromType only works with enums declared as Q_ENUM or Q_FLAG"); 
    const QMetaObject *metaObject = qt_getEnumMetaObject(T()); 
    const char *name = qt_getEnumName(T()); 
    return metaObject->enumerator(metaObject->indexOfEnumerator(name)); 
} 

名前を正しく取得しますが、最後の行でも無効なメタネームが返されます。

これを回避する手段はありますか? Qtメタ列挙体でプロセッサ定義を使用できますか?私はプリプロセッサコマンドを削除し、そのまま列挙型を持っているとします。コードは機能します。プリプロセッサが何かを壊すようです。

ありがとうございました! Qt 5.8を使用しています。

+0

「moc」は、_compiler predefined_マクロであるため、2つのマクロが分からないような気がします。あなたは '#ifdef Q_OS_WIN'と' Q_OS_LINUX'でもっとうまくいくかもしれません。 – Oktalist

答えて

1

私は確かに言うことはできませんが、あなたはそれがプリプロセッサコマンドの問題であることを観察したので、Qts MOCはプリプロセッサコマンドを処理できず、単に無視して登録しようとします同じ名前空間に同じ名前の2つの列挙型があります。これは明らかに正しく動作しません。

Qt5.8では、Q_ENUM_NSというマクロが導入されました。このマクロでは、名前空間のスコープでQt Metaobjectシステムで列挙型を登録できます。一緒にインライン名前空間で、次の操作を実行できます。

# ifdef _WIN32 
inline 
# endif 
namespace audio_win32 { 
    Q_NAMESPACE 
    enum AudioRenderer 
    { 
     Null, 
     OpenAL, 
     XAudio2 
    }; 
    Q_ENUM_NS(AudioRenderer) 
} // namespace audio_win32 

#ifdef _LINUX 
inline 
#endif 
namespace audio_linux { 
    Q_NAMESPACE 
    enum AudioRenderer 
    { 
     Null, 
     OpenAL, 
     ALSA 
    }; 
    Q_ENUM_NS(AudioRenderer) 
} // namespace audio_linux 

両方の列挙は異なる名前空間に住んでいるので、MOCはそれらの両方を登録し、問題を持っていない、そして現在のプラットフォームのための唯一の名前空間がインライン化されているので、 AudioRendererの名前はQMetaEnum::fromType<AudioRenderer>();で、常に正しいものを指します。

Q_NAMESPACEマクロを使用するには、これらの列挙型を定義するヘッダーファイルに#include <QObject>が必要です。

+0

これは、プリプロセッサを使用した場合に比べて、ちょっと気味が悪いので、理想的ではありませんが、動作します。しかし、私はその考えを感謝します。そして、次のカップルの日に何もうまくいかなければ、私はこれを受け入れたものとしてマークします。コードがコンパイルされてからバグのように感じましたが、実行時には動作しませんでした。 –

+0

@flash_fireプリプロセッサを使用して、インラインに名前空間を選択しています。私はあなたが遭遇した問題がMOCのバグであり、最初にコンパイルしてはならないことに同意します。 – Corristo

関連する問題