(1)在 QT 里任何类都继承于 QObject 类,以继承大师们的代码, 并借助于大师们的原有代码,来完成对象的析构与内存回收。与此同时,还有几个关键的类,也会被使用,现在根据它们的源码来学习它们。磨刀不误砍柴工。只有更好的了解了这些代码后,借助于以前大师们的劳动成果,才可以更流利地,写出更稳健的 QT 代码,知其然,知其所以然。
第一个要学习的类是 QMetaObject 。它的引出位置如下:
(2)由类 QObject 的成员函数 QObject :: metaObject ( ) 引出类 QMetaObject :
(3)引出 宏 Object 的源代码,看看其提供了哪些功能:
/* qmake ignore Q_OBJECT */
#define Q_OBJECT \
public: \
QT_WARNING_PUSH \
Q_OBJECT_NO_OVERRIDE_WARNING \
static const QMetaObject staticMetaObject; \
virtual const QMetaObject *metaObject() const; \
virtual void *qt_metacast(const char *); \
virtual int qt_metacall(QMetaObject::Call, int, void **); \
QT_TR_FUNCTIONS \
private: \
Q_OBJECT_NO_ATTRIBUTES_WARNING \
Q_DECL_HIDDEN_STATIC_METACALL static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **); \
QT_WARNING_POP \
struct QPrivateSignal {}; \
QT_ANNOTATE_CLASS(qt_qobject, "")
++分析该宏 QOBJECT 提供了哪些功能 :
(3) 由此得出类 QObject 的数据结构 :
(4)类 QObject 的简化版源码:
class Q_CORE_EXPORT QObject
{
Q_OBJECT
Q_PROPERTY(QString objectName //定义了 objectName 属性
READ objectName
WRITE setObjectName
NOTIFY objectNameChanged
BINDABLE bindableObjectName)
Q_DECLARE_PRIVATE(QObject) // 声明私有类
public:
Q_INVOKABLE explicit QObject(QObject *parent = nullptr);
virtual ~QObject();
template<typename T> //查找容器中孩子
inline T findChild(const QString &aName = QString(), //定义略
Qt::FindChildOptions options = Qt::FindChildrenRecursively) const { }
template<typename T>
inline QList<T> findChildren(const QString &aName = QString(),
Qt::FindChildOptions options = Qt::FindChildrenRecursively) const
{ QList<T> list; return list; }
#if QT_CONFIG(regularexpression)
template<typename T> //
inline QList<T> findChildren(const QRegularExpression &re,
Qt::FindChildOptions options = Qt::FindChildrenRecursively) const
{ QList<T> list; return list; }
#endif // QT_CONFIG(regularexpression)
//typedef QList<QObject *> QObjectList;
inline const QObjectList &children() const { return d_ptr->children; }
void setParent(QObject *parent); //此函数定义在这里,加入容器
static QMetaObject::Connection connect(
const QObject * sender , const char * signal,
const QObject * receiver, const char * member,
Qt::ConnectionType = Qt::AutoConnection);
static QMetaObject::Connection connect( //这俩是类的静态成员函数
const QObject * sender , const QMetaMethod & signal,
const QObject * receiver, const QMetaMethod & method,
Qt::ConnectionType type = Qt::AutoConnection);
inline QMetaObject::Connection connect( //基于对象的动态成员函数
const QObject * sender, const char * signal,
const char * member,
Qt::ConnectionType type = Qt::AutoConnection) const;
static bool disconnect( //解除信号与槽的静态成员函数
const QObject * sender , const char * signal,
const QObject * receiver, const char * member);
static bool disconnect(
const QObject * sender , const QMetaMethod &signal,
const QObject * receiver, const QMetaMethod &member);
inline bool disconnect( //动态函数默认由信号发送者调用
const char * signal = nullptr,
const QObject *receiver = nullptr,
const char * member = nullptr) const
{ return disconnect(this, signal, receiver, member); }
inline bool disconnect(
const QObject * receiver,
const char * member = nullptr) const
{ return disconnect(this, nullptr, receiver, member); }
static bool disconnect(const QMetaObject::Connection &);
void dumpObjectTree() const;
void dumpObjectInfo() const;
#ifndef QT_NO_PROPERTIES //这里出现了动态属性设置
bool setProperty (const char * name, const QVariant &value);
QVariant property(const char * name) const; //根据属性名获取属性值,形参是字符串
//作为对比 QMetaProperty QMetaObject::property(int index) const;
//根据属性索引返回值属性对象 QMetaProperty对象,形参是数字索引
QList<QByteArray> dynamicPropertyNames() const;
QBindingStorage *bindingStorage() { return &d_ptr->bindingStorage; }
const QBindingStorage *bindingStorage() const { return &d_ptr->bindingStorage; }
#endif // QT_NO_PROPERTIES
Q_SIGNALS:
void destroyed(QObject * = nullptr); //信号函数不需要实现
void objectNameChanged(const QString &objectName, QPrivateSignal);
public: //显示本对象所在的容器,或者说返回容器父类
inline QObject * parent() const { return d_ptr->parent; }
//而 QMetaObject :: superClass() 则返回继承父类
//用于判断本对象是否是形参类及其子类的实现
inline bool inherits(const char * classname) const
{ return const_cast<QObject *>(this)->qt_metacast(classname) != nullptr; }
//bool QMetaObject :: inherits(const QMetaObject * metaObject) 用于判断类的继承关系
public Q_SLOTS:
void deleteLater();
protected:
QObject * sender() const; //判断信号的发送者
int senderSignalIndex() const;
int receivers(const char *signal) const;
bool isSignalConnected(const QMetaMethod &signal) const;
protected:
QObject(QObjectPrivate &dd, QObject *parent = nullptr);
protected: //定义了本类的数据成员
QScopedPointer<QObjectData> d_ptr;
friend struct QMetaObject; //定义本类的友元类
friend struct QMetaObjectPrivate;
friend class QMetaCallEvent;
friend class QApplication;
friend class QApplicationPrivate;
friend class QCoreApplication;
friend class QCoreApplicationPrivate;
friend class QWidget;
friend class QAccessibleWidget;
friend class QThreadData;
private:
Q_DISABLE_COPY(QObject) //禁止对本类的复制操作
Q_PRIVATE_SLOT(d_func(), void _q_reregisterTimers(void *))
};
(4)
谢谢