[SOLVED] How does Q_DECLARE_METATYPE work?
I read on documentation that Q_DECLARE_METATYPE makes available type to QVariant, for example (I got it from documentation):
var.setValue(s); // copy s into the variant
// retrieve the value
MyStruct s2 = var.value<MyStruct>();
but can I call, for example, var.toString()?
How do I implement it?
I can't get the usefulness about all above and how it works ....
Does someone explain me?
I don't think ::toString() will work. But you know what your struct is, so you can stringify it yourself :)
The usefulness (although many will disagree) is that you can have a single type to pass between various parts of your code, without bothering about strict typing too much. Think about widget property browser in Qt Designer - some properties contain text, other just a boolean value, others might use some struct or binary data (ok, maybe not in Designer. But there are use cases where that would be true). You could write a super flexible set of classes and interfaces to make it work in "standard c++ way", but using a QVariant is simpler + the resulting code is in many cases easier to understand later.
So, for example, I can create a var (see above) as QVariant and pass it to all my functions without bothering about type ...
That could be complete if QVariant has a function to determine the type of object it carries inside ..
Have I understood?
Yes you are correct.
QVariant does have "::typeName()":http://qt-project.org/doc/qt-4.8/qvariant.html#typeName method, but of course it works only for built-in types. If your custom type is a QObject, you can always get the class name using QMetaObject.
But if I have to call for example "var.value<MyStruct>()" I have to know MyStruct name first to obtain the object ... how can I use QMetaObject?
Ah, there, you've hit the limit of QVariant :) In use cases I've encountered that has not been a problem, though. When I pass a special value to QVariant, I usually know about it, and know what to cast it to. Maybe passing the struct itself is better in your case?
I was wrong - you've almost hit the limit. There is "QVariant::userType()":http://qt-project.org/doc/qt-4.8/qvariant.html#userType and user type constructor: "QVariant":http://qt-project.org/doc/qt-4.8/qvariant.html#QVariant-3.
to make sure what type your QVariant (with custom object data) has, you can do the following:
@int metaTypeId = qRegisterMetaType<MyType>("MyType"); //will return a value >QVariant::UserType
QVariant v = ... ;//get your variant
if( v.userType() == metaTypeId )
Since QVariant::userType() will retun the MetaObject id if it's not a built in type.
Note: it's also safe to call qRegisterMetaType() multiple times. It will return the same result if it was called before. So you can call it from your constructor.
Thanks very much to all for explanations :)