Porting to Qt5 - issue with Q_PROPERTY(QVector<OwnClass>)
-
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? -
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 ?
-
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? -
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 -
@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; };
-
Why not use
QVector<Rule *>
?If you need to copy that object, you can add a clone function.
-
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 someqScriptRegisterMetaType
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 callingqRegisterMetaType
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. -
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!
-
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 someqScriptRegisterMetaType
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 callingqRegisterMetaType
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.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
QObject
s 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
andqRegisterMetaType
are not purposed to be used forQObject
derived classes. -
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
QObject
s 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
andqRegisterMetaType
are not purposed to be used forQObject
derived classes.@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? -
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.