简体   繁体   English

将QVariant中的枚举转换为整数

[英]Convert enums in QVariant into integers

I write a library which uses Qt's meta type system. 我写了一个使用Qt元类型系统的库。 The user of my library can provide values of custom types which get wrapped in a QVariant. 我的库的用户可以提供包含在QVariant中的自定义类型的值。 Later in some code internally in the library, I need to serialise this QVariant. 稍后在库中的一些代码中,我需要序列化这个QVariant。 I implemented serializers for a couple of types and I really don't need to support every type known to the Qt meta type system. 我为几种类型实现了序列化器,我真的不需要支持Qt元类型系统已知的每种类型。 I serialise the values in order to send them over the network using JSON. 我将这些值序列化,以便使用JSON通过网络发送它们。

But what I'd like to achieve is to support custom enum types, which the user has to register to the meta type system using qtRegisterMetaType<MyEnum>("MyEnum"); 但我想要实现的是支持自定义枚举类型,用户必须使用qtRegisterMetaType<MyEnum>("MyEnum");注册到元类型系统qtRegisterMetaType<MyEnum>("MyEnum"); anyway. 无论如何。 I want to serialise such an enum via converting it to an integer type. 我想通过将它转换为整数类型来序列化这样的枚举。

I tried QVariant::value<int>() on such an enum value, but it always returns 0. QVariant::canConvert<int>() returns false. 我在这样的枚举值上尝试了QVariant::value<int>() ,但它总是返回0. QVariant::canConvert<int>()返回false。

Is it possible (maybe using some dirty hacking) to get to the integer value of the wrapped enum? 是否有可能(可能使用一些脏黑客)获取包装枚举的整数值? How does Qt handle enum values in its meta type system? Qt如何处理元类型系统中的枚举值? Maybe I can just access the raw void* pointer when I'm sure that this is an enum value I have here. 也许当我确定这是我在这里的枚举值时,我可以访问原始的void*指针。

This leads us to the next question: How to check if a Qt meta type is a user enum type at all? 这引出了下一个问题: 如何检查Qt元类型是否完全是用户枚举类型?

Please note that since I'm writing internal code of the library, I can't use templates. 请注意,因为我正在编写库的内部代码,所以我不能使用模板。 The only "thing" I have is the QVariant, no compile-time type information. 我唯一的“东西”是QVariant,没有编译时类型信息。

// code in the project using my library:
MyEnum foo;
libraryFunction(foo);
// internal library code (note that compile-time type info isn't available):
QVariant foo = getValueAsVariant(...);
if (/* how to check if foo is an enum type? */)
    int enumValue = foo.value<int>(); // not working for enums!

I know that the C++ compiler can choose to use any integer type (not only 32-bit ones) internally to store enum values. 我知道C ++编译器可以选择在内部使用任何整数类型(不仅仅是32位)来存储枚举值。 Can this be a problem for me? 这对我来说可能是个问题吗? (If I reinterpret the void* as int* for example. But remember that the void* data is allocated by QVariant itself, so it may allocate more than, for example, 2 bytes for a enum with sizeof == 2 .) (例如,如果我将void*重新解释为int* 。但请记住, void*数据是由QVariant本身分配的,因此它可能为sizeof == 2的枚举分配超过2个字节。)

A dirty hack would be to serialize the QVariant to a QDataStream, then deserialize the last 4 bytes to an int. 脏的hack是将QVariant序列化为QDataStream,然后将最后4个字节反序列化为int。 This doesn't answer the question of how to check for an enum type. 这不回答如何检查枚举类型的问题。 I'll dig deeper into the moc output and update this. 我将深入研究moc输出并更新它。

Leemes has helpfully found that QMetaObject::enumerator() will give you all meta enums defined in a class. Leemes帮助发现QMetaObject::enumerator()将为您提供类中定义的所有元枚举。 This is enough for checking if a given type name is an enum or not, as one can convert the enum names to the type IDs using QMetaType::type() (but prepending the class name and "::"). 这足以检查给定的类型名称是否为枚举,因为可以使用QMetaType::type()将枚举名称转换为类型ID(但是可以在类名和“::”之前添加)。 In order to convert from QVariant holding an enum to an int, one simply reinterprets the QVariant::constData() as an int pointer and reads it. 为了从保存枚举的QVariant转换为int,只需将QVariant::constData()重新解释为int指针并读取它。 It works. 有用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM