Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. [SOLVED] Qt Meta-Obect System: QObject::setProperty() with QVariant user defined types - fails
Forum Updated to NodeBB v4.3 + New Features

[SOLVED] Qt Meta-Obect System: QObject::setProperty() with QVariant user defined types - fails

Scheduled Pinned Locked Moved General and Desktop
12 Posts 5 Posters 14.4k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • G Offline
    G Offline
    genC
    wrote on last edited by
    #1

    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 @QObject::setProperty(const char * fieldName, QVariant &value;)@
    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!

    1 Reply Last reply
    0
    • S Offline
      S Offline
      steno
      wrote on last edited by
      #2

      Do do you register the meta type with the call qRegisterMetaType("your custom meta type")?

      1 Reply Last reply
      0
      • G Offline
        G Offline
        genC
        wrote on last edited by
        #3

        Yes I tried with qRegisterMetaType, it didn't work either.

        1 Reply Last reply
        0
        • D Offline
          D Offline
          dangelog
          wrote on last edited by
          #4

          What's the (apparent) type of objVals?

          [quote]I have declared all the types with Q_DECLARE_METATYPE[/quote]

          Which types are you talking about exactly?

          [quote author="steno" date="1311784107"]Do do you register the meta type with the call qRegisterMetaType("your custom meta type")?[/quote]

          Not needed.

          Software Engineer
          KDAB (UK) Ltd., a KDAB Group company

          1 Reply Last reply
          0
          • S Offline
            S Offline
            steno
            wrote on last edited by
            #5

            [quote author="steno" date="1311784107"]Do do you register the meta type with the call qRegisterMetaType("your custom meta type")?[/quote]

            Not needed.[/quote]

            Doh, true. Only needed for queued signals/slots and the property system.

            1 Reply Last reply
            0
            • A Offline
              A Offline
              andre
              wrote on last edited by
              #6

              For the sake of trying to pinpoint what happens: if you try to set a property by directly entering its name instead of retreiving it from your array, and then calling setProperty on the QObject* pointer, does that work?

              I mean: what happens if you use:
              @
              myQObjectPtr->setProperty('ThePropertyOfTheSubclass', QVariant("a value"));
              @

              1 Reply Last reply
              0
              • G Offline
                G Offline
                genC
                wrote on last edited by
                #7

                bq. peppe wrote:
                What’s the (apparent) type of objVals?

                The type of objVals is QObject** (array of QObject pointers).

                bq. 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
                @class Class1 : public QObject {
                Q_OBJECT

                public:
                Class1() {
                }

                virtual ~Class1() {
                }
                

                };

                Q_DECLARE_METATYPE(Class1*)@

                Then I have another class Class2 containing a reference to Class1
                @class MyClass : public QObject {
                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;
                }
                

                };@

                bq. Andre wrote:
                I mean: what happens if you use:
                @myQObjectPtr->setProperty('ThePropertyOfTheSubclass', QVariant("a value"));@

                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[])
                {
                QCoreApplication a(argc, argv);

                MyClass mc;
                QObject* c = new Class1;
                
                QVariant value;
                value.setValue(c);
                
                if (mc.setProperty("cl",value) == false)
                    cout<<"setProperty failed"<<endl;
                
                return a.exec&#40;&#41;;
                

                }
                @

                header file (MyClasses.h)
                @#ifndef MYCLASSES_H
                #define MYCLASSES_H

                #include <QObject>
                #include <QVariant>
                #include <QMetaObject>

                class Class1: public QObject {
                Q_OBJECT
                public:
                virtual ~Class1() {}
                };

                Q_DECLARE_METATYPE(Class1*)

                class MyClass: public QObject {
                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
                @

                1 Reply Last reply
                0
                • D Offline
                  D Offline
                  dangelog
                  wrote on last edited by
                  #8

                  No, that code is wrong -- the type of the QVariant is QObject*, which does not match the type of the property (Class1*). Therefore the setProperty will fail. Create your QVariant from a Class1* value and it will work.

                  Yes, it's a kind of limitation of the whole QMetaType stuff...

                  Software Engineer
                  KDAB (UK) Ltd., a KDAB Group company

                  1 Reply Last reply
                  0
                  • G Offline
                    G Offline
                    genC
                    wrote on last edited by
                    #9

                    Ok that's what I assumed, but I hoped there was something else.

                    Thank you all for your help!

                    1 Reply Last reply
                    0
                    • G Offline
                      G Offline
                      genC
                      wrote on last edited by
                      #10

                      Oh, one last thing: why can't the QVariant of type QObject* be converted to a Class1* (using QVariant::convert(Type t))?

                      Thanks

                      1 Reply Last reply
                      0
                      • A Offline
                        A Offline
                        alexisdm
                        wrote on last edited by
                        #11

                        [quote author="genC" date="1311851619"]Oh, one last thing: why can't the QVariant of type QObject* be converted to a Class1* (using QVariant::convert(Type t))?[/quote]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");.

                        1 Reply Last reply
                        0
                        • G Offline
                          G Offline
                          genC
                          wrote on last edited by
                          #12

                          I see.
                          Well in fact, I'm using both composition and aggregation, so QObjects as children might not really work for me...

                          Thank you

                          1 Reply Last reply
                          0

                          • Login

                          • Login or register to search.
                          • First post
                            Last post
                          0
                          • Categories
                          • Recent
                          • Tags
                          • Popular
                          • Users
                          • Groups
                          • Search
                          • Get Qt Extensions
                          • Unsolved