2015-07-21 30 views
0

我有一个班,我用Q_PROPERTY来创建属性。我还在我的课堂定义开始时定义了Q_OBJECT。然而,我没有继承QObject,因为这使得这个类是不可复制的,这给了我编译错误的地方。我真的需要继承QObject以使Q_PROPERTY正常工作吗?在那种情况下 - 我能以某种方式解决不可复制的问题吗?Qt Q_PROPERTY是否需要我的类继承QObject?

+2

不,您不需要从'QObject'继承。使用'Q_GADGET':http://doc.qt.io/qt-5/qobject.html#Q_GADGET –

+0

@RA。我也需要这些信号,是否有办法绕过不可复制的问题? –

+2

在这种情况下,您将需要从'QObject'继承,并且将不会有任何方法绕过不可复制的问题。 –

回答

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_GADGETs可以具有Q_ENUM,Q_PROPERTY和Q_INVOKABLE,但它们不能 具有信号或槽

Q_GADGET使一个类的成员,staticMetaObject,可用。 staticMetaObject的类型为QMetaObject,并提供对使用Q_ENUMS声明的 枚举的访问。

我想如果你已经有父对象Q_OBJECT的QObject然后Q_GADGET对于其他情况需要反射。

+0

我没有阅读上面的评论。 – AlexanderVX

+0

除继承QObject和放置Q_OBJECT宏之外,是否还有其他要求?当我尝试使用一个属性时,我仍然收到“没有成员命名”错误。 –

+0

然后请分享代码。从QObject继承,添加Q_OBJECT宏。添加Q_PROPERTY宏。添加READ和/或WRITE属性C++方法。请注意,这应该转到头文件,并且如果在.cpp实现文件中这样做,预处理器(MOC编译器)将无法生成生成的代码。 – AlexanderVX

0

为了能够使用的信号,你需要声明Q_OBJECT宏,你可以在文档中找到:

的Q_OBJECT宏必须出现在声明自己的信号类定义的私有部分,插槽或使用由Qt的元对象系统提供的其他服务的插槽。

而对于Q_PROPERTY:

这个宏用于继承QObject的类声明的属性。

所以你可以看到你需要从QObject的

继承
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,但它是相当没有意义的,如果你不还复制它的孩子,性能等,只有你能确定是什么语义将对象副本需要。在很多情况下,我会考虑一个可复制的对象是一个丑陋的黑客。