QObject对象(The QObject)

正如介绍中描述的,QObject是Qt的内省机制。在Qt中它几乎是所有类的基类。值类型除外,例如QColorQStringQList

Qt对象是一个标准的C++对象,但是它具有更多的功能。可以从两个方向来深入探讨:内省和内存管理。内省意味着Qt对象知道它的类名,它与其它类的关系,以及它的方法和属性。内存管理意味着每个Qt对象都可以成为是其它子对象的父对象。父对象拥有子对象,当父对象销毁时,它也会负责销毁它的子对象。

理解QObject的能力如何影响一个类最好的方法是使用Qt的类来替换一个典型的C++类。如下所示的代表一个普通的类。

Person是一个数据类,包含了一个名字和性别属性。Person使用Qt的对象系统来添加一个元信息到c++类中。它允许使用Person对象的用户连接槽函数并且当属性变化时获得通知。

  1. class Person : public QObject
  2. {
  3. Q_OBJECT // enabled meta object abilities
  4. // property declarations required for QML
  5. Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
  6. Q_PROPERTY(Gender gender READ gender WRITE setGender NOTIFY genderChanged)
  7. // enables enum introspections
  8. Q_ENUMS(Gender)
  9. public:
  10. // standard Qt constructor with parent for memory management
  11. Person(QObject *parent = 0);
  12. enum Gender { Unknown, Male, Female, Other };
  13. QString name() const;
  14. Gender gender() const;
  15. public slots: // slots can be connected to signals
  16. void setName(const QString &);
  17. void setGender(Gender);
  18. signals: // signals can be emitted
  19. void nameChanged(const QString &name);
  20. void genderChanged(Gender gender);
  21. private:
  22. // data members
  23. QString m_name;
  24. Gender m_gender;
  25. };

构造函数传入父对象到超类中并且初始化成员变量。Qt的值类型类会自动初始化。在这个例子中QString
将会初始化为一个空字符串(QString::isNull())并且性别成员变量会明确的初始化为未知性别。

  1. Person::Person(QObject *parent)
  2. : QObject(parent)
  3. , m_gender(Person::Unknown)
  4. {
  5. }

获取函数在命名在属性后并且是一个简单的const函数。使用设置属性函数当属性被改变时会发送改变信号。为此我们插入一个保护用来比较当前值与新值。只有在值不同时我们指定给成员变量的值才会生效,并且发送改变信号。

  1. QString Person::name() const
  2. {
  3. return m_name;
  4. }
  5. void Person::setName(const QString &name)
  6. {
  7. if (m_name != name) // guard
  8. {
  9. m_name = name;
  10. emit nameChanged(m_name);
  11. }
  12. }

类通过继承QObject,我们获得了元对象能力,我们可以尝试使用metaObject()的方法。例如从对象中检索类名。

  1. Person* person = new Person();
  2. person->metaObject()->className(); // "Person"
  3. Person::staticMetaObject.className(); // "Person"

QObject基类和元对象还有其它很多功能。详情请查看QMetaObject文档获取更多信息。