View Full Version : Avoiding Q_DECLARE_METATYPE
moijhd
10th July 2013, 16:55
Hi,
I have a standard C++ object.
class A
{
// ...
};
I can't (and I don't want to) define it as a Qt type.
Though, I still like to put it in the model (QStandardItemModel for instance).
So far, I was able to but a raw pointer into the model with the very ugly following code :
// I have
const A &a = ; //...
// Writing
item->setData(
qVariantFromValue(
reinterpret_cast<void*>(
const_cast<A*>(
&a
)
)
),
Role
);
// Reading
const A &a = *reinterpret_cast<A*>(
const_cast<const void*>(
item->data(Role).value<void*>()
)
);
How bad is this ?
Anything better ?
Thanks !
PS0 : I read the method with Q_DECLARE_METATYPE.
PS1 : I could always create an intermediate Qt type which would embed my non Qt type...but that seems heavy too.
Santosh Reddy
10th July 2013, 17:21
Would this look simpler
...
QStandardItem item;
...
const A a0;
...
item.setData(reinterpret_cast<unsigned int>(&a), Role);
...
const A & a1 = *reinterpret_cast<const A*>(item.data(Role).toUInt());
//or
const A & a2 = *reinterpret_cast<const A*>(modelIndex.data(Role).toUInt());
...
moijhd
10th July 2013, 20:13
Okay for the casts factorisation, and the "toUInt()" simplification.
What the difference between the "void*" and the "unsigned int" casts ?
I suppose most machines will accept them indifferently. Though, I might have to mind about portability. So I guess the safest move id to go with "void*" ? But "unsigned int" simplifies a lot :D
ChrisW67
10th July 2013, 22:25
Why avoid the macro and invent work that can be hidden in the QVariant class for you?
moijhd
11th July 2013, 08:36
What if I have no control over the type ie the type is defined in a library ? I have to create a header include the library and including the Q_DECLARE_METATYPE and I will link that file when I need the meta type ? Fair enough.
By the way, can we guard Q_DECLARE_METATYPE through Qt ?
ChrisW67
11th July 2013, 09:19
What if I have no control over the type ie the type is defined in a library ?
If the type has a default constructor and can be copied then you can store it in a QVariant.
If the class does not meet the requirements then you can store a pointer (const or not) in a QVariant.
You need to arrange somewhere that Q_DECLARE_METATYPE() is invoked before you try to use the 3rd party type in a QVariant.
#include <QtCore>
// From some library header
class AClass {
public:
AClass() { }
~AClass() { }
AClass(const AClass &other) { }
};
class BClass {
public:
BClass() { }
~BClass() { }
private:
BClass(const BClass &other) { } // cannot be copied
};
// end of header
Q_DECLARE_METATYPE(AClass)
Q_DECLARE_METATYPE(const BClass*)
int main(int argc, char **argv) {
QCoreApplication app(argc, argv);
AClass aa;
QVariant av = QVariant::fromValue(aa);
// later
AClass ar = av.value<AClass>();
const BClass bb;
QVariant bv = QVariant::fromValue(&bb);
// later
const BClass *br = bv.value<const BClass*>();
return 0;
}
By the way, can we guard Q_DECLARE_METATYPE through Qt ?
I have no idea what this means.
moijhd
11th July 2013, 10:09
Ok thanks !
Guard for me :D
#ifndef Q_DECLARE_METATYPE_AClass
#define Q_DECLARE_METATYPE_AClass
Q_DECLARE_METATYPE(AClass)
#endif
Powered by vBulletin® Version 4.2.5 Copyright © 2024 vBulletin Solutions Inc. All rights reserved.