QApplication的故事

QApplication是很常用的Qt类,随便创建一个带有QmainWindow项目就会自动创建QApplication对象,QApplication向上继承QGuiApplication,QGuiApplication向上继承QCoreApplication,QCoreApplication向上继承QObject,QObject再向上就没有了。

继承完QGuiApplication后引入一个Q_OBJECT宏,用Ctrl+鼠左进入是qobjectdefs.h,这个Q_OBJECT是在qapplication.h引入的头文件QtCore/qcoreapplication.h里#include <QtCore/qcoreapplication.h>,但又不是直接在qcoreapplication.h里,而是在qcoreapplication.h引入的头文件qobject.h里,qobject.h则直接引入了qobjectdefs.h。

class Q_WIDGETS_EXPORT QApplication : public QGuiApplication
{
    Q_OBJECT

也就是说qobjectdefs.h被qobject.h引入,qobject.h被qcoreapplication.h引入,qcoreapplication.h被qapplication.h引用,所以这个Q_OBJECT是已经被定义的。回看QApplication的祖先,依次是QGuiApplication、QCoreApplication、乃至QObject本身都有一个Q_OBJECT,并且他们中Q_OBJECT宏都来自于qobjectdefs.h的定义。 那为什么不复用,由第一个引用qobjectdefs.h的qobject.h不断向下被继承,而是要在他的子类们不断的引入Q_OBJECT宏?因为Q_OBJECT宏没有被初始化,相当于在每次创建引入Q_OBJECT宏的类的对象的时候单独单独初始化了Q_OBJECT宏。从侧面反应了Qt的复用的前提是解耦合,如果不能解耦合宁可不复用

#define Q_OBJECT \ 
public: \ //公共
    QT_WARNING_PUSH \ //qcompilerdetection.h中的宏,__pragma(warning(push))将当前警告等级压入栈中,来源于qcompilerdetection.h的引入头文件#include <QtCore/qobjectdefs_impl.h>↑#include <QtCore/qnamespace.h>↑#include <QtCore/qglobal.h>↑#include <QtCore/qcompilerdetection.h>
    Q_OBJECT_NO_OVERRIDE_WARNING \ //定义是空的,没有启用元对象系统就不需要警告信息
    static const QMetaObject staticMetaObject; \ //定义了一个名为staticMetaObject的静态常量,类型为QMetaObject
    virtual const QMetaObject *metaObject() const; \ //定义了一个虚函数,返回值类型为const QMetaObject*
    virtual void *qt_metacast(const char *); \ //定义了一个虚函数,参数为一个字符串指针
    virtual int qt_metacall(QMetaObject::Call, int, void **); \ //定义了一个虚函数,参数为一个枚举类型和两个整数和一个指向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 **); \ //定义了一个静态函数,用于在运行时调用对象的静态成员函数,以支持元对象系统。Q_DECL_HIDDEN_STATIC_METACALL定义是空的,
    QT_WARNING_POP \ //qcompilerdetection.h中QT_WARNING_POP宏定义为__pragma(warning(pop))将当前警告等级pop出栈,
    struct QPrivateSignal {}; \ //定义了一个空结构体QPrivateSignal
    QT_ANNOTATE_CLASS(qt_qobject, "") //QT_ANNOTATE_CLASS宏定义为(type, ...),(type, ...)(qt_qobject, "")注解一个类,qt_qobject是该类使用的标识符,空字符串""是附加信息
...

回看继承那一行 

class Q_WIDGETS_EXPORT QApplication : public QGuiApplication
{   //Q_WIDGETS_EXPORT宏定义为__declspec(dllimport) 在qcompilerdetection.h中,
    //class __declspec(dllimport) QApplication : public QGuiApplication表明在Windows平台上,QApplication 的定义是由某个动态链接库(DLL)中实现的,在程序运行时动态加载。
    Q_OBJECT

那Q_OBJECT的故事暂且告一段落,目前只需知道他是定义了信号和槽,往下看下图QApplication,太多了,只说共性的问题, Q_PROPERTY宏为QApplication类定义了多个属性

    Q_PROPERTY(QIcon windowIcon READ windowIcon WRITE setWindowIcon)
    Q_PROPERTY(int cursorFlashTime READ cursorFlashTime WRITE setCursorFlashTime)
    Q_PROPERTY(int doubleClickInterval  READ doubleClickInterval WRITE setDoubleClickInterval)
    Q_PROPERTY(int keyboardInputInterval READ keyboardInputInterval WRITE setKeyboardInputInterval)
#if QT_CONFIG(wheelevent)
    Q_PROPERTY(int wheelScrollLines  READ wheelScrollLines WRITE setWheelScrollLines)
#endif
#if QT_DEPRECATED_SINCE(5, 15)
    Q_PROPERTY(QSize globalStrut READ globalStrut WRITE setGlobalStrut)
#endif
    Q_PROPERTY(int startDragTime  READ startDragTime WRITE setStartDragTime)
    Q_PROPERTY(int startDragDistance  READ startDragDistance WRITE setStartDragDistance)
#ifndef QT_NO_STYLE_STYLESHEET
    Q_PROPERTY(QString styleSheet READ styleSheet WRITE setStyleSheet)
#endif
    Q_PROPERTY(bool autoSipEnabled READ autoSipEnabled WRITE setAutoSipEnabled)

再往下看,太长了,只能计数了,需要的话自己去Ctrl+鼠左键配合ai去读代码。

public://公共,可用对象访问
#ifdef Q_QDOC //构造开始
    QApplication(int &argc, char **argv);
#else
    QApplication(int &argc, char **argv, int = ApplicationFlags);
#endif         //构造结束
    virtual ~QApplication();

    static <class> <fun>;        //伪代码,返回3个有关样式的方法
    enum ColorSpec { NormalColor=0, CustomColor=1, ManyColor=2 };
#if QT_DEPRECATED_SINCE(5, 8)    //不详开始
    QT_DEPRECATED static int colorSpec();
    QT_DEPRECATED static void setColorSpec(int);
#endif // QT_DEPRECATED_SINCE(5, 8)
#if QT_DEPRECATED_SINCE(5, 0)
    QT_DEPRECATED static inline void setGraphicsSystem(const QString &) {}
#endif                            //不详结束

    using QGuiApplication::palette;
    static <class> <fun>(<ars>)//伪代码,3个静态方法

#if QT_VERSION < 0x060000 // remove these forwarders in Qt 6
    static <class> <fun>(<ars>)//伪代码,2个静态方法
#endif

    static QWidgetList allWidgets();//伪代码,12个静态方法    

#if QT_DEPRECATED_SINCE(5, 0)
    QT_DEPRECATED static inline void syncX() {}
#endif
    static <class> <fun>(<ars>);//伪代码,20个静态方法
    bool notify(QObject *, QEvent *) override;
...                                //一系列方法和其实现的条件

Q_SIGNALS:                        //信号
    void focusChanged(QWidget *old, QWidget *now);

public:                            //第二个公共方法
    QString styleSheet() const;
public Q_SLOTS:
#ifndef QT_NO_STYLE_STYLESHEET
    void setStyleSheet(const QString& sheet);
#endif
    void setAutoSipEnabled(const bool enabled);
    bool autoSipEnabled() const;
    static void closeAllWindows();
    static void aboutQt();

protected:                        //protected方法2个
    bool event(QEvent *) override;
    bool compressEvent(QEvent *, QObject *receiver, QPostEventList *) override;

private:                          //私有方法,友元12个它们可以访问我的成员
    Q_DISABLE_COPY(QApplication)
    Q_DECLARE_PRIVATE(QApplication)

    friend class QGraphicsWidget;
    friend class QGraphicsItem;
    friend class QGraphicsScene;
    friend class QGraphicsScenePrivate;
    friend class QWidget;
    friend class QWidgetPrivate;
    friend class QWidgetWindow;
    friend class QTranslator;
    friend class QWidgetAnimator;
#ifndef QT_NO_SHORTCUT
    friend class QShortcut;
    friend class QLineEdit;
    friend class QWidgetTextControl;
#endif
    friend class QAction;

#ifndef QT_NO_GESTURES
    friend class QGestureManager;
#endif
};

QT_END_NAMESPACE

#endif // QAPPLICATION_H

结语,要搞清楚一个类,要从它的父类开始搞起,因为父类是成员最少的,同时,要不知道父类有什么却在子类中用到就会一头雾水,这是哪来的。但这也只是个思维框架,记不住所有成员,用的大概率是用的时候再去查。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值