QDebug with custom typed QVariant
-
Hi all,
I am having a custom type which I use with QVariant. Everything works fine here.
One thing I seem not be able to do though is to properly serialize it to debug output.
For instance:QColor colr; QVariant colorv = QVariant::fromValue(colr); qDebug() << colorv;
generates such output:
QVariant(QColor, QColor(Invalid))
My type generates such:
QVariant(Point3F, )
My type is registered with Q_DECLARE_METATYPE and has its own << operator defined which is never called:
Q_DECLARE_METATYPE(Point3F); QDebug operator << (QDebug, const Point3F&);
Anyone knows how I can ensure stream operator is called if I stream the variant containing my type ?
Cheers!
-
You need a custom streaming operator for QDebug. Here is an example in the docs for QDebug.
[edit:koahnig] Sorry, I did not see the part related to QVariant. I guess that would as if converted back to your original object.
probably likeqDebug() << colorv.value<QColor>();
-
Yes, that probably would work but thats what I would like to avoid doing, since I log many different types with the single log function.
Somehow, for Qt types like QSize and QColor streaming the QVariant into QDebug works just fine. Their streaming operators are called.
I would like to find out what needs to be done for custom types in order for QVariant to actually call the custom stream handler.Probably, there is a way to install my handler for particular custom type but I am not sure.
Looking into the code I could see the following for QVariant:
QDebug operator<<(QDebug dbg, const QVariant &v) { QDebugStateSaver saver(dbg); const uint typeId = v.d.type; dbg.nospace() << "QVariant("; if (typeId != QMetaType::UnknownType) { dbg << QMetaType::typeName(typeId) << ", "; bool userStream = false; bool canConvertToString = false; if (typeId >= QMetaType::User) { userStream = QMetaType::debugStream(dbg, constData(v.d), typeId); canConvertToString = v.canConvert<QString>(); } if (!userStream && canConvertToString) dbg << v.toString(); else if (!userStream) handlerManager[typeId]->debugStream(dbg, v); } else { dbg << "Invalid"; } dbg << ')'; return dbg; }
If I could somehow make my type convertable to QString maybe it would work, though I dont know how to accomplish it.
-
Hi,
What does your custom debug << operator do ?
-
Hi!
Nothing special just logs some data:
QDebug operator << (QDebug debug, const Point3F& point) { QDebugStateSaver saver(debug); debug.nospace() << "Point3F(" << point.x() << ", " << point.y() << ", " << point.z() << ")"; return debug; }
Note that if I do stream the object directly it works as expected e.g.:
qDebug() << Point3F();
Shows:
Point3F(0, 0, 0)
It is just when the object is inside of QVariant, the logging is broken.
-
I am not sure if it is possible or how to add the file here with a sample project but there is the full example for anyone interested to test:
#include <QCoreApplication> #include <QString> #include <QVariant> #include <QDebug> #include <QSize> class MyClass { public: MyClass() {} MyClass(const QString& text) : m_text(text) {} MyClass(const MyClass& other) : m_text(other.text()) {} const QString& text() const { return m_text; } private: QString m_text; }; Q_DECLARE_METATYPE(MyClass); QDebug operator << (QDebug debug, const MyClass& object) { debug.nospace() << "MyClass(" << object.text() << ")"; return debug; } int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); MyClass myClass("This is my text"); QVariant vMyClass = QVariant::fromValue(myClass); // Qt type for which everything works just fine qDebug() << QSize(); qDebug() << QVariant::fromValue(QSize()); qDebug() << myClass; // This produces: MyClass("This is my text") qDebug() << vMyClass; // This procudes: QVariant(MyClass, ) // while it should: QVariant(MyClass, MyClass("This is my text") ) return app.exec(); } I have tested on Ubuntu, Qt 4.8.1 and Qt 5.6.0
-
I believe you need to register the debug stream operator.