列挙型クラスタイプでQ_DECLARE_METATYPE()を使用する方法はありますか?古い列挙型が機能することは知っていますが、これらの新しい、強く型付けされた列挙型はどうですか?この問題に関するものは他に見つかりません。入手可能な最新のQtバージョンを使用しています。
例:
enum Foo
{
A,
B,
C
};
Q_DECLARE_METATYPE(Foo)
QVariant var = Foo::A; // works fine
enum class Bar
{
X,
Y,
Z
};
Q_DECLARE_METATYPE(Bar)
QVariant var = Bar::X; // doesn't compile
これは、単純な古いenum
を使用する場合:
_enum Foo { A, B, C };
QVariant var = Foo::A;
_
実際、コンパイラは次のコンストラクタを使用してvar
インスタンスを構築します。
_QVariant(const QVariant& other);
_
さらに、other
インスタンスは、次の非明示的なコンストラクターを使用して作成されます。
_QVariant(int val);
_
古いenums
はを整数値として扱うことができるため、これは可能です。
要約すると、これはコンパイラが舞台裏で見て実行することです:
_int temp = Foo::A;
QVariant var = QVariant(temp);
_
ご存知のように、_enum class
_ esCAN NOTは、明示的なキャストなしで整数値として扱われます。したがって、コンパイラーは、型を暗黙的にint
に変換し、一致するコンストラクターを呼び出すことはできません(正確には、使用可能なすべてのコンストラクターからの最良の候補)。つまり、QVariant
が提供するコンストラクターの事前定義されたセットがあります。 _Q_DECLARE_METATYPE
_マクロを使用して新しいマクロを追加することはできません。
独自のタイプでQVariant
を使用するには、むしろ QVariant::fromValue(const T& t)
関数を使用する必要があります。
_enum class Foo { A, B, C };
QVariant var = QVariant::fromValue(Foo::A);
_
または代わりに:
_enum class Foo { A, B, C };
QVariant var;
var.setValue(Foo::A);
_
Qt 5.5で追加された Q_ENUM を使用できます。
enum class Bar
{
X,
Y,
Z
};
Q_ENUM(Bar)
QVariant var = QVariant::fromValue(Bar::X);
QVariant::fromValue
を使用して提案されたソリューションを試しましたが、次のタイプのコンパイラエラーが発生し続けました。
タイプが登録されていません。Q_DECLARE_METATYPEマクロを使用して、Qtのメタオブジェクトシステムに認識させてください。
私の回避策は、列挙型をint
型を必要とする関数に渡すときに、列挙値を明示的にQVariant
にキャストすることでした。私の場合、QComboBox
アイテムを追加して、それをキャストするときです。値の取得時に列挙型クラスタイプに戻ります。
元の質問のコンテキストでは、これは次のようなものになります。
enum class Foo { A, B, C };
// Elsewhere, adding item to QComboBox.
m_comboBox->addItem(tr("A"), static_cast<int>(Foo::A));
// Value retrieval from QComboBox item, somewhere else.
const auto foo { static_cast<Foo>(m_comboBox->currentData().value<int>()) };