Conversion operators for custom metatypes
-
I'm using some custom metatypes, with Q_DECLARE_METATYPE, and I use them in QVariants. I would like to make these types work with .toString() and/or .toInt(), mostly to be able to easily save the values in a xml file, along other values of various types.
I'm guessing I need to implement some kind of template function, but I have no idea what I need exactly, and I couldn't find anything about this.
Thanks in advance.
-
The conversions to QString QVariant uses are built-in, they are not template functions or other generic methods. Your best option is to just add toString()/toInt() methods to your custom type(s) and use those instead of the QVariant methods. Eg: @myVariant.value<MyType>().toString();@
So you can see what I mean, I'll walk a QVariant::toString() call:
QVariant::toString() calls qVariantToHelper<QString>(): "/src/corelib/kernel/qvariant.cpp:2147":https://qt.gitorious.org/qt/qt/blobs/4.8/src/corelib/kernel/qvariant.cpp#line2147
qVariantToHelper<QString> calls QVariant::hander->convert(): "/src/corelib/kernel/qvariant.cpp:2119":https://qt.gitorious.org/qt/qt/blobs/4.8/src/corelib/kernel/qvariant.cpp#line2119
convert then does the "magic" of converting from known types to QString (and the other built-in conversions) by running through switch blocks: "src/corelib/kernel/qvariant.cpp:624":https://qt.gitorious.org/qt/qt/blobs/4.8/src/corelib/kernel/qvariant.cpp#line624 -
As far as I remember this was beeing discussed for Qt 5, but I'm not quite sure if it actually made it in (IRC or the developer mailing list might be of use here).
See also "QTBUG-14940":https://bugreports.qt-project.org/browse/QTBUG-14940.
-
Would subclassing QVariant and overloading .toString be a good design? My only issue is that the class needs the symbols of all my custom types, which is not ideal.
This also allows me to add .toString for some Qt types that don't have it, like QRect and such.Something like:
@QString MyVariant::toString() const
{
switch (type())
{
case QVariant::Rect:
QRect rect = toRect();
return QString::number(rect.left())+";"+QString::number(rect.top())+";"+QString::number(rect.right())+";"+QString::number(rect.bottom());
break;case QVariant::RectF: QRectF rectF = toRectF(); return QString::number(rectF.left())+";"+QString::number(rectF.top())+";"+QString::number(rectF.right())+";"+QString::number(rectF.bottom()); break; case QVariant::UserType: switch (userType()) { //... }
}
return QVariant::toString();
}@Also, I'm guessing I can do the same with .convert to allow conversion from a string?
-
You could subclass QVariant, but it would probably be easier to just create a separate function (as opposed to a method) that does the work, and avoid the maintenance overhead of subclassing.