Qt-具有枚举类类型的Q_DECLARE_METATYPE()

Qt - Q_DECLARE_METATYPE() with an enum class type

本文关键字:DECLARE METATYPE 枚举 类型 Qt-      更新时间:2023-10-16

是否有方法将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 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);

您可以使用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的元对象系统知道

我的工作是在将枚举值传递到需要QVariant类型的函数时,将其显式强制转换为int,在我的情况下,添加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>()) };