Solved Casting a custom class to QVariant
-
I'm trying to provide a way to convert a custom (
QObject
derived) class to aQVariant
using a custom method. The main purpose of this would be outputting data about the class into aQJsonDocument
.I tried defining a cast operator as such:
operator QVariant() const { return QVariant(this->statusMap()); // statusMap() method returns a QVariantMap with relevant data }
But I'm getting an error of the form:
error: ‘QVariant::QVariant(void*)’ is private within this context QVariant status = (QVariant)m_server->getExtension(extensionName); ^
I have also declared the class as a QMetaType using
Q_DECLARE_METATYPE
but the result is the same.Is there even a way to do this? I cannot find a method such as
QObject::toVariant
or similar that I could override anywhere in the docs, so if there is such a thing I don't see it.Thanks.
-
@Onyx said in Casting a custom class to QVariant:
QVariant(this->statusMap())
Use QVariant::fromValue<>() instead.
-
@sierdzio Ah, that's a static, makes sense. One part I still don't understand is that I get
use of deleted function...
for constructors now. Poking around a bit, is this because I declared the class usingQ_DECLARE_METATYPE
but don't have my own copy constructors (what I found online seems to suggest copy constructor forQObject
is private?).Also, I should note that this class inherits from another class, and they are both inheriting from
QObject
, I assume this might be causing problems as well? So basically currently it's:class Class1 : public QObject { Q_OBJECT ... } Q_DECLARE_METATYPE(Class1) class Class2 : public Class1 { Q_OBJECT ... } Q_DECLARE_METATYPE(Class2)
Should I omit the
Q_OBJECT
and/orQ_DECLARE_METATYPE
macros fromClass2
or do I need them in both places? Sorry for all the extra questions, but I can't seem to find specific examples involving inheritance anywhere... -
- Every QObject should have the Q_OBJECT macro in the header file. No need to change that
- Multiple inheritance from 2 QObject classes is not allowed in Qt
- Copying QObjects is not allowed in Qt and does not make sense. The copy constructor is private for a reason! You can copy the pointer (memory address), but not the object. If you really want to "copy" a QObject, you need to create a new one and make sure it is properly parented
- I totally fail to see what you're trying to achieve ;-) Why you try to return QVariantMap in original post but start talking about QObjects in the last comment? How are the objects related to the variant map?
-
@sierdzio said in Casting a custom class to QVariant:
Every QObject should have the Q_OBJECT macro in the header file. No need to change that
Makes sense, I was pretty sure it was the case but...
@sierdzio said in Casting a custom class to QVariant:
Multiple inheritance from 2 QObject classes is not allowed in Qt
I don't have multiple inheritance though.
Class1
inheritsQObject
,Class2
inheritsClass1
. Unless my understanding of terminology is wrong, that shouldn't be a problem (and was not up to this point).@sierdzio said in Casting a custom class to QVariant:
Copying QObjects is not allowed in Qt and does not make sense. The copy constructor is private for a reason! You can copy the pointer (memory address), but not the object. If you really want to "copy" a QObject, you need to create a new one and make sure it is properly parented
Again, makes sense. I think it was just me googling and finding different threads online that led me to a wrong conclusion on what I need to do, probably doesn't have anything to do with my specific issue.
@sierdzio said in Casting a custom class to QVariant:
I totally fail to see what you're trying to achieve ;-) Why you try to return QVariantMap in original post but start talking about QObjects in the last comment? How are the objects related to the variant map?
Yeah, I explained that poorly... Taking the same hierarchy from before, I'm trying to provide a way to cast
Class2
toQVariant
. Currently, it provides a method calledstatusMap
that returns aQVariantMap
with the info I need.So, basically, I want this:
QVariant data = (QVariant)Class2;
Unless I misunderstood, this should allow me to do something like:
QJsonDocument data = QJsonDocument::fromVariant(Class2);
Is this wrong?
The reason I asked about
Q_DECLARE_METATYPE
stuff is that, from my understanding of the docs, if I want that to work my class needs to be registered in Qt's metatype system. But trying to do that results in compile errors, so I'm trying to figure out what I'm doing wrong.Maybe my whole approach is wrong, or maybe it's not even doable... On reflection, I should've probably led with that.
Thanks for all the clarifications so far either way :)
-
@Onyx said in Casting a custom class to QVariant:
I don't have multiple inheritance though. Class1 inherits QObject, Class2 inherits Class1. Unless my understanding of terminology is wrong, that shouldn't be a problem (and was not up to this point).
Yes that is OK.
Taking the same hierarchy from before, I'm trying to provide a way to cast Class2 to QVariant. Currently, it provides a method called statusMap that returns a QVariantMap with the info I need.
So, basically, I want this:
QVariant data = (QVariant)Class2;
Unless I misunderstood, this should allow me to do something like:
QJsonDocument data = QJsonDocument::fromVariant(Class2);If you want to serialize to JSON, I think going through a variant map is only needlessly adding complexity here. Consider serializing to JSON directly in your class and returning a QJsonObject or QJsonArray. Example: https://github.com/sierdzio/stimeline/blob/master/src/scalendar.h#L38
As for making an unified serialization framework, see how QDataStream has overloads added to many Qt classes - this is probably the best way to do it (in your case, the overloads will be for QJson* classes, of course).
The reason I asked about Q_DECLARE_METATYPE stuff is that, from my understanding of the docs, if I want that to work my class needs to be registered in Qt's metatype system
Pointers to QObjects are declared to metatype system automatically.
-
@sierdzio said in Casting a custom class to QVariant:
If you want to serialize to JSON, I think going through a variant map is only needlessly adding complexity here. Consider serializing to JSON directly in your class and returning a QJsonObject or QJsonArray. Example: https://github.com/sierdzio/stimeline/blob/master/src/scalendar.h#L38
That might indeed be the simplest solution. I'll have to check if I even need any serialization past going directly to JSON (it's not a fresh project, I'm refactoring an existing one), but it sounds like a good idea in any case.
@sierdzio said in Casting a custom class to QVariant:
As for making an unified serialization framework, see how QDataStream has overloads added to many Qt classes
Ah, that's a place I didn't think to look into. I hoped it would just be a case of adding a
toVariant
method to my classes or similar initially, but since I couldn't find anything like that I went the casting route. Will take a peek in there.@sierdzio said in Casting a custom class to QVariant:
Pointers to QObjects are declared to metatype system automatically.
Oh, that's nice. Good to know.
Thanks for all the pointers, I'll mark this as solved since it seems I took the wrong route anyway.