PDA

View Full Version : QVariant::toString and custom data types



Vladimir
16th January 2007, 10:25
I'm trying to use Q_PROPERTY as a quick way to represent my computational classes in GUI (and possibly to serialize them in XML). I've build simple model that shows all properties of the given object and it works well. But some of the properties are of custom types (fixed-length vectors etc.) and I want to show them too. Of course I can write code like this



if(p.userType() == qMetaTypeId<Vector2d>()) {
Vector2d v = p.read(_item).value<Vector2d>();
return QString("(%1, %2)").arg(v[0]).arg(v[1]);
} else if(p.userType() == ...)


but this makes adding new types harder, and I should duplicate this code in many places.

Later I've found that QVariant can serialize custom types to QDataStream using operator<< provided by type, but it provides only binary serialization. Are there any way to implement serialization to text ? Something like toString but which can handle user-defined types ?

camel
16th January 2007, 11:19
Something like toString but which can handle user-defined types ?

Not very nice, but you could do something like this:
(insert Pseudo-code/compile on own risk disclaimer here ;-)

Header:


namespace VariantConversion {
QString (*VariantToStringFunction)(const QVariant &);

void registerVariantToStringFunction(int usertype,
VariantToStringFunction function);

QString variantToString(const QVariant &variant);
}


Implementation


Q_GLOBAL_STATIC(QReadWriteLock, getLock)
typedef QMap<int, VariantConversion::VariantToStringFunction> FunctionMap;
Q_GLOBAL_STATIC(FunctionMap, getFunctionMap)

void VariantConversion::registerVariantToStringFunction (int usertype,
VariantToStringFunction function)
{
QWriteLocker writeLock(&getLock());
functionMap[usertype] = function;
}

QString VariantConversion::variantToString(const QVariant &variant)
{
int type = variant.userType();
if (type < QVariant::UserType) {
return variant.toString();
}
QReadLocker readLock(&getLock());
if (getFunctionMap().contains(type)) {
return (getFunctionMap()[type])(variant);
}
qDebug("No registered function to convert Variant of type "
"\"%s\" to QString", QMetaType::typeName(type));
return QString();
}


EDIT: I thought about it more, and having a lock in a static variable inside of a function is not the greatest idea, and kind of braindead, at least in older compilers.... (Look up thread safety of static variables)

I do not think Q_GLOBAL_STATIC is public API at this point, but you can find information about it on the web:
http://delta.affinix.com/2006/01/31/q_global_static/
http://article.gmane.org/gmane.comp.kde.devel.core/39118

Vladimir
16th January 2007, 15:36
Thanks a lot for quick reply ! You solution works good for me.