PDA

View Full Version : problem with qvariant_casting to a usertype



skydave
26th June 2009, 02:20
Hi I have the following and I guess very stupid questions:

I have defined a usertype which I store in a qvariant. In my app I later try to get the data (which is a class pointer) out of the qvariant via

myVariant.value<MyClass *>();

But the returned value is a zero pointer. I have tracked the problem down to this code in qvariant.h(line 564 qt4.5.0):

template<typename T> T qvariant_cast(const QVariant &v)
{
const int vid = qMetaTypeId<T>(static_cast<T *>(0)); // returns 257 which is the typeid of MyClass*
if (vid == v.userType()) //PROBLEM: v.userType returns 256
return *reinterpret_cast<const T *>(v.constData()); // wont get executed...but should be
if (vid < int(QMetaType::User)) {
T t;
if (qvariant_cast_helper(v, QVariant::Type(vid), &t))
return t;
}
return T(); // zero pointer (in debug mode)
}

The function compars the typeid of my userdata which is 257 with the userType value returned from v. Only when they are the same the function actually casts the constData into MyClass*. But when one has more Userdata types (than one) those all get an id bigger than 256 which is the base id of all userdata type ids. So this comparison seems quite weird to me.

I know that the qtcode is working as it should and therefore I guess I have some big missunderstanding of userdata type ids and their usage. Can someone help me and shed some light on how I get my userdata casted correctly?

Many thanks in advance,
David

P.S.: Hi All, great forum!

caduel
26th June 2009, 08:31
please show us your code where you declare your custom variant type and where you use it

skydave
26th June 2009, 09:31
Hi caduel,

I do it quite the usual way I guess. ViewStateInfo derives from QObject somewhere up in the inheritance chain. Thanks for taking a look mate.

So this is the header of the usertype.

#pragma once
#include "ViewStateInfo.hpp"



namespace composer
{
namespace model
{
//
//
//
class LabelStateInfo : public ViewStateInfo
{
public:

LabelStateInfo(); // constructor


// [...]

private:
};
}
}
Q_DECLARE_METATYPE(composer::model::LabelStateInfo *)

David

wysota
26th June 2009, 09:38
QVariant can accept pointers to QObject right out of the box so you don't have to declare the metatype for your own class - you can store it normally and then after retrieving it, cast it to proper type.

skydave
26th June 2009, 10:35
Hi Wysota, thanks for your reply.

I will try what you proposed once Im at home. I didnt know that and it sounds like a good idea especially because I have a templated wrapper to the qvariant casting in my app already.

Out of curiosity: In theory what I was trying to do should work, shouldnt it?

Cheers,
David

wysota
26th June 2009, 11:23
Yes, but without seeing the actual code it is hard to say what you did wrong.

skydave
28th June 2009, 14:22
Hi, sorry but I like to bring this up again (as I hate unsolved problems and the proposed workaround of using QObjects would pose some nasty additional expenses on client code side):

The thing is, that the qmetatype registration obviously seems to work because my type has an id(257) which is successfully retrieved within qvariant_cast. So if you register a couple of usertypes shouldnt they get all an id from 256+ ?

I try to find out whether the usertype registration is working or not. And from what I see it is working. And if it is working then there really isnt anything else I can do wrong, isnt there?

David

P.S.: does somebody understand the == comarison in line 4 of the initial code snippet and explain it to me? I would expect it to be >= since there isnt only one usertype of id 256 qvariant_cast may cast to, but there are any numbers 256+

wysota
28th June 2009, 15:58
Can you show us the exact code you use?