Q_OBJECT 宏
对于开始使用 Qt 的人来说,Q_OBJECT 宏可能是最奇怪的事情之一。
Qt QObject 类说:Q_OBJECT 宏必须出现在声明自己的信号和槽或使用 Qt 元对象系统提供的其他服务的类定义的私有部分中。
class MyClass : public QObject
{
Q_OBJECT
public:
MyClass(QObject *parent = 0);
~MyClass();
signals:
void mySignal();
public slots:
void mySlot();
};
所以,听起来我们需要它来使用信号和槽,并且可能还用于其他目的(与元对象相关)。
另一个与moc相关的文档解释说:
元对象编译器 moc 是处理 Qt 的 C++ 扩展的程序。
moc 工具读取 C++ 头文件。如果它找到一个或多个包含 Q_OBJECT 宏的类声明,它会生成一个 C++ 源文件,其中包含这些类的元对象代码。除此之外,信号和槽机制、运行时类型信息和动态属性系统都需要元对象代码。
关于Signal and Slot的另一个文档:
所有包含信号或槽的类都必须在其声明的顶部提及 Q_OBJECT。它们还必须(直接或间接)从 QObject 派生。
请注意,当我们想在信号和插槽之间建立连接时,我们实际上是使用Object作用域进行的:
QObject::connect(sender, signal, receiver, slot):
是否总是需要 Q_OBJECT 宏?
- 快速回答:没有。
- 更好的答案:嗯,把它一直放在那里。
实际上,只有当 moc 工具必须生成元对象代码才能使用信号和插槽机制、运行时类型信息、动态属性系统和用于国际化的翻译功能时,才需要 Q_OBJECT 宏。
虽然可以在没有 Q_OBJECT 宏和元对象代码的情况下使用 QObject 作为基类,但如果不使用 Q_OBJECT 宏,则信号和槽以及此处描述的其他功能都将不可用。
总的来说,似乎所有 Qt 开发人员都强烈建议对 QObject 的每个子类使用 Q_Object,无论他们是否实际使用上面列出的功能。