[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):
@
struct MyStruct
{
int i;
...
};Q_DECLARE_METATYPE(MyStruct)
@
@
MyStruct s;
QVariant var;
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 :)