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. Porting to Qt5 - issue with Q_PROPERTY(QVector<OwnClass>)
QtWS25 Last Chance

Porting to Qt5 - issue with Q_PROPERTY(QVector<OwnClass>)

Scheduled Pinned Locked Moved Unsolved General and Desktop
11 Posts 4 Posters 5.4k Views
  • 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.
  • J Offline
    J Offline
    JulienMaille
    wrote on last edited by JulienMaille
    #1

    I have started porting my application to Qt5 and I stumbled upon an issue that did not show up with Qt 4.8

    In one of my class I define a Q_PROPERTY

    Q_PROPERTY(QVector<Rule> rules MEMBER rules)
    

    and this is the compile error I get

    C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\INCLUDE\xutility(2737): error C2678: binary '==' : no operator found which takes a left-hand operand of type 'const Rule' (or there is no acceptable conversion)
    

    Rule is a pretty simple class, derive from QObject. I tried adding Q_DECLARE_METATYPE(Rule) but it doesn't help.
    I'm not sure why that "const" shows up in the error message. Do you have any clue what could be wrong?

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi,

      Then there's something that's fishy with your code. You shouldn't be able to create a QVector of QObject based objects.

      Did you by any chance implement the assignment and copy operators for your Rule class ?

      By the way, why do you need it to be a QObject ?

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      1
      • J Offline
        J Offline
        JulienMaille
        wrote on last edited by JulienMaille
        #3

        Thanks for taking time to answer.
        Pretty sure I have implemented assign/copy operators for this class, will check ASAP.
        That or the Q_NO_COPY macro are required in order to use QVector<QObject> right? Or is it just impossible? The code use to work without issue in Qt4.8
        One of the reasons Rule inherits from QObject it that QVector<Rule> is exposed to scripts using QtScript and QObjects are automagically exposed thanks to the Meta-Object system. Rule doesn't have slots/signal only Q_PROPERTY.
        Is it possible/recommended to use QGadget instead?

        1 Reply Last reply
        0
        • VRoninV Offline
          VRoninV Offline
          VRonin
          wrote on last edited by
          #4

          Please read http://doc.qt.io/qt-5/qobject.html#no-copy-constructor-or-assignment-operator
          if you don't use signals and slots switch to a plain class with the Q_GADGET macro

          "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
          ~Napoleon Bonaparte

          On a crusade to banish setIndexWidget() from the holy land of Qt

          1 Reply Last reply
          2
          • J Offline
            J Offline
            JulienMaille
            wrote on last edited by JulienMaille
            #5

            @VRonin said:

            Q_GADGET

            I will give it a try EDIT: it doesn't help, I have the exact same error message + qRegisterMetaType now fails
            Here is what the class look like (I'm still wondering why it was fine with Qt4)

            class Rule : public QObject
            {
                Q_OBJECT
                Q_PROPERTY(QString name MEMBER name)
                Q_PROPERTY(int diameter MEMBER diam)
                Q_PROPERTY(QVector<double> sBoundaries MEMBER sBoundaries)
                Q_PROPERTY(QVector<double> dBoundaries MEMBER dBoundaries)
                Q_PROPERTY(QVector<int> sCriteria MEMBER sCriteria)
                Q_PROPERTY(QVector<int> dCriteria MEMBER dCriteria)
            
            public:
                Rule(QObject* parent = 0) : QObject(parent), zoneName("name"), diam(50)
                {
                    sBoundaries << 1 << 3;
                    dBoundaries << 0 << 4;
                    sCriteria << -1 <<  4 << 0;
                    dCriteria << -1 << -1 << 2;
                }
                Rule &operator=(const Rule & other)
                {
                    const QMetaObject* metaObject = other.metaObject();
                    for( int i=metaObject->propertyOffset(); i<metaObject->propertyCount(); ++i )
                        setProperty(metaObject->property(i).name(), other.property(metaObject->property(i).name()));
                    return *this;
                }
                Rule(const Rule& other) {*this = other;}
            
                QString zoneName;
                int diam;
                QVector<double> sBoundaries, dBoundaries;
                QVector<int> sCriteria, dCriteria;
            };
            
            1 Reply Last reply
            0
            • SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on last edited by
              #6

              Why not use QVector<Rule *> ?

              If you need to copy that object, you can add a clone function.

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              1 Reply Last reply
              0
              • J Offline
                J Offline
                JulienMaille
                wrote on last edited by JulienMaille
                #7

                That's what I plan to do but it's still unclear to me what changes in Qt5 broke my (probably bad) design.

                I'm also having linkage issues on custom classes that I expose to QtScript with qScriptRegisterMetaType. Does the class implementation has to be fully known for this to work? Again it was working fine with Qt4.8 by just including the header file. It seems that the linker is now looking for the moc_ file which I'm almost sure wasn't the case with Qt4.8
                Also it seems that some qScriptRegisterMetaType calls are now useless because I've removed some of them and I can still use those class in my scripts ... weird it's like calling qRegisterMetaType is enough now.

                Maybe I'm doing it wrong. All I want is to access from QtScript existing Q_Objects that live in my c++ code
                I don't need to be able to instanciate them in scripts, I don't need to copy them, etc.

                kshegunovK 1 Reply Last reply
                0
                • J Offline
                  J Offline
                  JulienMaille
                  wrote on last edited by
                  #8

                  Ok well it looks like Q_DECLARE_OPAQUE_POINTER() is what I need here, but again any recommendations of a better design (if possible) will be appreciated. Thanks for your help!

                  1 Reply Last reply
                  0
                  • J JulienMaille

                    That's what I plan to do but it's still unclear to me what changes in Qt5 broke my (probably bad) design.

                    I'm also having linkage issues on custom classes that I expose to QtScript with qScriptRegisterMetaType. Does the class implementation has to be fully known for this to work? Again it was working fine with Qt4.8 by just including the header file. It seems that the linker is now looking for the moc_ file which I'm almost sure wasn't the case with Qt4.8
                    Also it seems that some qScriptRegisterMetaType calls are now useless because I've removed some of them and I can still use those class in my scripts ... weird it's like calling qRegisterMetaType is enough now.

                    Maybe I'm doing it wrong. All I want is to access from QtScript existing Q_Objects that live in my c++ code
                    I don't need to be able to instanciate them in scripts, I don't need to copy them, etc.

                    kshegunovK Offline
                    kshegunovK Offline
                    kshegunov
                    Moderators
                    wrote on last edited by kshegunov
                    #9

                    @JulienMaille

                    I don't need to be able to instanciate them in scripts, I don't need to copy them, etc.

                    Then why are you defining a copy constructor and an assignment operator for QObjects when you were specifically told not to do it?

                    Rule(const Rule& other) {*this = other;}    //< This, by the way, is wrong at the C++ level as well.
                    Rule &operator=(const Rule & other);
                    

                    Additionally Q_DECLARE_METATYPE and qRegisterMetaType are not purposed to be used for QObject derived classes.

                    Read and abide by the Qt Code of Conduct

                    J 1 Reply Last reply
                    0
                    • kshegunovK kshegunov

                      @JulienMaille

                      I don't need to be able to instanciate them in scripts, I don't need to copy them, etc.

                      Then why are you defining a copy constructor and an assignment operator for QObjects when you were specifically told not to do it?

                      Rule(const Rule& other) {*this = other;}    //< This, by the way, is wrong at the C++ level as well.
                      Rule &operator=(const Rule & other);
                      

                      Additionally Q_DECLARE_METATYPE and qRegisterMetaType are not purposed to be used for QObject derived classes.

                      J Offline
                      J Offline
                      JulienMaille
                      wrote on last edited by JulienMaille
                      #10

                      @kshegunov said:

                      you're doing it wrong

                      Well the problem is with Qt4.8 at least:

                      Any class or struct that has a public default constructor, a public copy constructor, and a public destructor can be registered with Q_DECLARE_METATYPE

                      So the trick is to only use it on pointers to QObjects?
                      Or is it totally useless for QObject derived class?

                      1 Reply Last reply
                      0
                      • SGaistS Offline
                        SGaistS Offline
                        SGaist
                        Lifetime Qt Champion
                        wrote on last edited by
                        #11

                        The usage description of Q_DECLARE_METATYPE is the same in Qt 5.

                        But anyway, yes use a QVector<Rules *> that's how it's intended to be used.

                        Interested in AI ? www.idiap.ch
                        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                        1 Reply Last reply
                        1

                        • Login

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