I have a class where I use Q_PROPERTY
to create properties. I also have defined Q_OBJECT
in the beginning of my class definition. I however have NOT inherited QObject
, because that makes the class non-copyable and this gives me compile errors everywhere. Do I really need to inherit QObject
for the Q_PROPERTY
to work? And in that case - can I somehow go around the non-copyable issue?

- 2,515
- 5
- 37
- 81
-
2No, you don't need to inherit from `QObject`. Use `Q_GADGET`: http://doc.qt.io/qt-5/qobject.html#Q_GADGET – RA. Jul 21 '15 at 15:35
-
@RA. I also need the signals, is there a way to circle around the non-copyable issue? – ulak blade Jul 21 '15 at 15:36
-
2In that case, you will need to inherit from `QObject`, and there won't be any way to circle around the non-copyable issue. – RA. Jul 21 '15 at 15:38
-
2Signals and copying won't work. What should a signal/slot connection do if the sender or receiver is copied? I think that'd be semantically broken. – Frank Osterfeld Jul 21 '15 at 15:39
-
so I can never have a QList of things that inherit QObject? – ulak blade Jul 21 '15 at 15:47
-
1@ulakblade You can have a `QList` of pointers to `QObject` instances (or things that inherit from `QObject`). That is, `QList
`. – RA. Jul 21 '15 at 15:51 -
`QObject` is a composite already, you don't need to use collection types such as `QList` with it. – Kuba hasn't forgotten Monica Jul 21 '15 at 20:40
3 Answers
Does Qt Q_PROPERTY require my class to inherit QObject?
Simple answer is: if you use Q_OBJECT then yes, and if you use Q_GADGET then no.
To provide Q_PROPERTY (as property in QML) or Q_INVOKABLE as (callable method in QML) you need the object able to deal with reflection. It is achievable by either Q_OBJECT (which requires QObject as class parent) or Q_GADGET (which does not require QObject as class parent).
http://doc.qt.io/qt-5/qobject.html#Q_GADGET
Q_GADGET
The Q_GADGET macro is a lighter version of the Q_OBJECT macro for classes that do not inherit from QObject but still want to use some of the reflection capabilities offered by QMetaObject. Just like the Q_OBJECT macro, it must appear in the private section of a class definition.
Q_GADGETs can have Q_ENUM, Q_PROPERTY and Q_INVOKABLE, but they cannot have signals or slots
Q_GADGET makes a class member, staticMetaObject, available. staticMetaObject is of type QMetaObject and provides access to the enums declared with Q_ENUMS.
I think if you already have QObject for parent use Q_OBJECT macro then and Q_GADGET for the rest of cases when you need reflection.

- 8,351
- 4
- 38
- 47
-
Is there something else required other than inheriting QObject and placing the Q_OBJECT macro? I am still getting a "has no member named" error when I try to use a property. – ulak blade Jul 22 '15 at 08:15
-
Please share the code then. Inherit from QObject, Add Q_OBJECT macro. Add Q_PROPERTY macro. Add READ and/or WRITE property C++ methods. Please note that that should go to header and if you do that in .cpp implementation file that the preprocessor (MOC compiler) won't be able to produce generated code. – Alexander V Jul 22 '15 at 21:10
To be able to use signals you need to declare the Q_OBJECT macro as you can find in the documentation:
The Q_OBJECT macro must appear in the private section of a class definition that declares its own signals and slots or that uses other services provided by Qt's meta-object system.
And for the Q_PROPERTY:
This macro is used for declaring properties in classes that inherit QObject.
so as you can see you need to inherit from QObject

- 766
- 10
- 25
Your question misses the forest for the trees: why do you need QObject
to be copyable? QObject
is a composite and can hold any number of child objects. It's usually unnecessary to put QObject
instances into collections, since a QObject
already acts as an object collection.
For example:
// Wrong, won't compile
QList<QObject> objects;
// OK, leverage the compositeness of QObject
QObject objects;
(new QObject(&objects))->setObjectName("obj1");
(new QObject(&objects))->setObjectName("obj2");
for (auto obj : objects.children()) qDebug() << obj->objectName();
// OK, use C++11 collections
std::list<QObject> objects;
objects.emplace_back();
objects.emplace_back();
objects.front().setObjectName("obj1");
objects.back().setObjectName("obj2");
for (const QObject & obj : objects) qDebug() << obj.objectName();
If you really need to copy a QObject
, you can certainly do so, but it's rather pointless if you don't also copy its children, properties, etc. Only you can determine what semantics would an object copy need to have. In many cases, I'd consider a copyable object to be an ugly hack.

- 1
- 1

- 95,931
- 16
- 151
- 313