我有一个类,我使用Q_PROPERTY
来创建属性。我也在类定义的开头定义了Q_OBJECT
。但是我没有继承QObject
,因为这使得该类不可复制,这给了我各处的编译错误。我是否真的需要继承QObject
才能使Q_PROPERTY
正常工作?在那种情况下 - 我可以以某种方式绕过不可复制的问题吗?
答案 0 :(得分:4)
Qt Q_PROPERTY是否要求我的类继承QObject?
简单的答案是:如果你使用Q_OBJECT,那么是,如果你使用Q_GADGET,那么没有。
要提供Q_PROPERTY(作为QML中的属性)或Q_INVOKABLE(QML中的可调用方法),您需要能够处理反射的对象。它可以通过Q_OBJECT(需要QObject作为类父类)或Q_GADGET(它不需要QObject作为类父类)来实现。
http://doc.qt.io/qt-5/qobject.html#Q_GADGET
Q_GADGET
Q_GADGET宏是Q_OBJECT宏的较轻版本 不从QObject继承但仍希望使用某些类的类 QMetaObject提供的反射功能。就像 Q_OBJECT宏,它必须出现在类的私有部分中 定义
Q_GADGET可以有Q_ENUM,Q_PROPERTY和Q_INVOKABLE,但它们不能 有信号或插槽
Q_GADGET使类成员staticMetaObject可用。 staticMetaObject的类型为QMetaObject,可以访问 使用Q_ENUMS声明的枚举。
我想如果您已经有QObject用于父级使用Q_OBJECT宏,那么当Q_GADGET用于其他需要反射的情况时。
答案 1 :(得分:0)
为了能够使用您需要声明Q_OBJECT宏的信号,您可以在文档中找到:
Q_OBJECT宏必须出现在类定义的私有部分中,该部分定义声明自己的信号和插槽,或者使用Qt的元对象系统提供的其他服务。
对于Q_PROPERTY:
此宏用于在继承QObject的类中声明属性。
因此您可以看到您需要从QObject继承
答案 2 :(得分:0)
你的问题错过了树林:为什么你需要QObject
可以复制? QObject
是一个复合,可以容纳任意数量的子对象。将QObject
个实例放入集合通常是不必要的,因为QObject
已经充当了对象集合。
例如:
// 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();
如果你真的需要复制QObject
,你可以certainly do so,但如果你不复制其子女,财产等,那就毫无意义了。只有你可以确定对象副本需要具有的语义。在许多情况下,我认为可复制对象是一个丑陋的黑客。