[SOLVED] Qt Meta-Obect System: QObject::setProperty() with QVariant user defined types - fails
Hello all,
Here is my case: I have a class, MyClass, that has references to other objects (composition). I want to dynamically initialize an instance of this class using
The properties are pointers to objects that inherit QObjects. I have those pointers stored in a QObject* array (let’s call it objVals) and I also have the field names in an array fieldNames.
To do this, I create a QVariant (let’s call it value) for each QObject* in the array, then call setProperty() with fieldNames[i] and value.
For example
- MyClass mc;
- for (int i = 0; i < numObjFields; ++i) {
- QVariant value;
- value.setValue(objVals[i]);
- mc.setProperty(fieldNames[i],value);
- }
if the properties’ real type is not QObject*, but a derived class, setProperty fails.
Now if I cast objVals[i] to it’s true type, it succeeds (assuming I know the type at compile time of course)
- MyClass mc;
- for (int i = 0; i < numObjFields; ++i) {
- QVariant value;
- value.setValue((trueType*)objVals[i]);
- mc.setProperty(fieldNames[i],value);
- }
I have declared all the types with Q_DECLARE_METATYPE, Q_OBJECT and the properties with Q_PROPERTY with the proper getters and setters.
Why is this problem happennig? Is there a way to overcome it? Your help will be very much appreciated.
Thanks!
11 replies
peppe wrote:
What’s the (apparent) type of objVals?
The type of objVals is QObject** (array of QObject pointers).
peppe wrote:
Which types are you talking about exactly?
I have created my own classes, that inherit QObject. I’m registering the pointers to those classes.
For example
- Q_OBJECT
- public:
- Class1() {
- }
- virtual ~Class1() {
- }
- };
- Q_DECLARE_METATYPE(Class1*)
Then I have another class Class2 containing a reference to Class1
- Q_OBJECT
- Q_PROPERTY (Class1* cl READ getCl WRITE setCl)
- Class1* cl;
- public:
- MyClass() {
- cl = NULL;
- }
- Class1* getCl() const {
- return cl;
- }
- void setCl(Class1 *obj) {
- cl = obj;
- }
- };
Andre wrote:
I mean: what happens if you use:
It doesn’t work either
Here is a sample code that you can compile and run to troubleshoot the problem (Qt console application)
main.cpp:
- #include <QtCore/QCoreApplication>
- #include <iostream>
- #include "MyClasses.h"
- using namespace std;
- int main(int argc, char *argv[])
- {
- MyClass mc;
- QVariant value;
- value.setValue(c);
- if (mc.setProperty("cl",value) == false)
- cout<<"setProperty failed"<<endl;
- return a.exec();
- }
header file (MyClasses.h)
- #ifndef MYCLASSES_H
- #define MYCLASSES_H
- #include <QObject>
- #include <QVariant>
- #include <QMetaObject>
- Q_OBJECT
- public:
- virtual ~Class1() {}
- };
- Q_DECLARE_METATYPE(Class1*)
- Q_OBJECT
- Q_PROPERTY (Class1* cl READ getCl WRITE setCl)
- Class1* cl;
- public:
- MyClass() {
- cl = NULL;
- }
- Class1* getCl() const {
- return cl;
- }
- void setCl(Class1 *obj) {
- cl = obj;
- }
- virtual ~MyClass() {}
- };
- #endif // MYCLASSES_H
Oh, one last thing: why can’t the QVariant of type QObject* be converted to a Class1* (using QVariant::convert(Type t))?Because QVariant::type() returns 2 different type ids for Class1* and QObject*, and you can see in the source code of QVariant::canConvert(Type) that if the two type ids are different the functions returns false except for a few hard-coded conversions between Qt builtin types or between numeric types.
But if it’s really a composition and not an aggregation, you could just add the QObjects as children, and give them names (QObject::setObjectName) to find them later with yourContainerObject->findChild<Class1*>(“yourObjectName”);.
You must log in to post a reply. Not a member yet? Register here!



