PDA

View Full Version : Simplified problem about enums and QVariants.



hickscorp
8th August 2011, 19:38
Ok i believe the problem i have posted before is too complicated to be read now. Lets make the question simple:
Can someone provide me with an example of code showing how to construct a QVariant "v", based on a given QVariant::UserType "t" where "t" refers to a type registered for an enum type?
Then when using qDebug() << v; i expect the type as well as the value to appear in stdout...

i don't think i can go for a more simple question :)

Thanks,
Pierre.

wysota
9th August 2011, 07:31
I don't know if that helps you in any way but here goes:

class Cls : public QObject {
Q_OBJECT
public:
enum X {
A, B = 13, C
}
Q_ENUMS(X);

};

Q_DECLARE_METATYPE(Cls::X)

#include "main.moc"

int main(){

int xMT = qRegisterMetaType<Cls::X>("Cls::X");
qDebug() << "Type id:" << xMT;
QVariant v = qVariantFromValue(Cls::B);
qDebug() << v;
Cls::X x = v.value<Cls::X>();
qDebug() << x;
QMetaEnum en = Cls::staticMetaObject.enumerator(0);
qDebug() << en.value(0) << en.value(1) << en.value(2);
qDebug() << "Key for Cls::B is:" << en.valueToKey(Cls::B);
qDebug() << "Key for v is:" << en.valueToKey(v.value<Cls::X>());
qDebug() << "Key for v is:" << en.valueToKey(*(int*)v.data());
return 0;
}

and the output:

Type id: 258
QVariant(Cls::X, )
13
0 13 14
Key for Cls::B is: B
Key for v is: B
Key for v is: B

MarekR22
9th August 2011, 09:28
@wysota: here (http://www.qtcentre.org/threads/43725-Enums-to-QVariants-and-comparing-those-after-the-conversion.) is his initial thread. In short he want handle any kind of enums! His code doesn't know what enum will be used, only meta data for enum (name as C-string or QMetaEnum object) are available.

wysota
9th August 2011, 10:09
I know. The last version of code (casting to integer) will handle that case. There is not much magic in QVariant, at some point you need to know (in terms of symbols and not variables) what type to cast the data to. Since all enums are in fact integers, casting to an int should be fairly safe.

hickscorp
9th August 2011, 10:35
@MarekR22: Exactly. In Wysota's code, the enum is template-constructed with the type Cls::X, which is not something i can do (Unless i make a branch of "if"s comparing metatype IDs and template constructing QVariants, but i thought this was already being generated at MOC'ing time).

@Wysota: Thanks for the snippet, but you are constructing the QVariant with "qVariantFromValue(Cls::B);", and i was asking to be able to construct it with the type ID (In your snippet: the xMT variable is holding it).

i guess i'm close to the solution since using the 3rd QVariant constructor (http://doc.qt.nokia.com/latest/qvariant.html#QVariant-3) makes the QVariant aware of the right type (In the QDebug, i get the right type as output), but i still get no value and using toInt won't work... However using a cast on the internal constData does, so i guess i'll have to stick to it...


The last version of code (casting to integer) will handle that case.
Exactly. That's what i'm doing already (See previous post here: http://www.qtcentre.org/threads/43725-Enums-to-QVariants-and-comparing-those-after-the-conversion. ) but when qDebug()'ing those variants, the value doesn't appear...

Thanks anyways, alot :)
And if you know better or have any good idea for me, i'd be very gratefull at this point.
Pierre.

wysota
9th August 2011, 10:50
@Wysota: Thanks for the snippet, but you are constructing the QVariant with "qVariantFromValue(Cls::B);", and i was asking to be able to construct it with the type ID (In your snippet: the xMT variable is holding it).
It doesn't matter how you create the variant. You can see that the data is there as you can cast it back to the proper type.


i guess i'm close to the solution since using the 3rd QVariant constructor (http://doc.qt.nokia.com/latest/qvariant.html#QVariant-3) makes the QVariant aware of the right type (In the QDebug, i get the right type as output)
You can see I can get that without any problems as well.


, but i still get no value and using toInt won't work...
It won't work. Custom types are not castable to anything.


but when qDebug()'ing those variants, the value doesn't appear...
It won't appear because there are no operators for your custom enum type defined. QVariant simply can't handle this case and goes for a sane default, showing just the type and not the value. There is no relation between your custom type and the QMetaEnum for the class that encapsulates it so Qt can't handle it. It's possible you could try creating a class that is able to provide such relationship (and then resolve it when needed) and register that class with QVariant and then wrap your enum in this class but it's complicated and probably doesn't fit your usecase very well.


And if you know better or have any good idea for me, i'd be very gratefull at this point.
Stick with casting to int*, just make sure the compiler treats your enum as int and not short or something else as you might get weird results.