18

有没有办法将 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
4

3 回答 3

25

这是因为当您使用普通的 old 时enum

enum Foo { A, B, C };
QVariant var = Foo::A;

编译器实际上使用以下构造函数来构建您的var实例:

QVariant(const QVariant& other);

更进一步,other实例是使用以下非显式构造函数创建的:

QVariant(int val);

这是可能的,因为 oldenums 可以被视为整数值。

总而言之,这是编译器在幕后看到和做的:

int temp = Foo::A;
QVariant var = QVariant(temp);

如您所知,enum classes不能在没有显式转换的情况下被视为整数值。因此,编译器无法将您的类型隐式转换为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);
于 2014-08-26T20:32:32.390 回答
7

您可以使用Qt 5.5 中添加的Q_ENUM :

enum class Bar
{
    X,
    Y,
    Z
};
Q_ENUM(Bar)

QVariant var = QVariant::fromValue(Bar::X);
于 2018-10-19T22:52:07.920 回答
0

尝试使用建议的解决方案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>()) };
于 2019-11-12T13:15:01.597 回答