关于Qt中的Q_D,Q_Q

11 篇文章 0 订阅

扒了下QComboBox的源码,里面使用了大量的Q_D,Q_Q宏,记录一下:

#define Q_D(Class) Class##Private * const d = d_func()
#define Q_Q(Class) Class * const q = q_func()

看看d_func和q_func:

template <typename T> static inline T *qGetPtrHelper(T *ptr) { return ptr; }
template <typename Wrapper> static inline typename Wrapper::pointer qGetPtrHelper(const Wrapper &p) { return p.data(); }

#define Q_DECLARE_PRIVATE(Class) \
    inline Class##Private* d_func() { return reinterpret_cast<Class##Private *>(qGetPtrHelper(d_ptr)); } \
    inline const Class##Private* d_func() const { return reinterpret_cast<const Class##Private *>(qGetPtrHelper(d_ptr)); } \
    friend class Class##Private;

#define Q_DECLARE_PRIVATE_D(Dptr, Class) \
    inline Class##Private* d_func() { return reinterpret_cast<Class##Private *>(qGetPtrHelper(Dptr)); } \
    inline const Class##Private* d_func() const { return reinterpret_cast<const Class##Private *>(qGetPtrHelper(Dptr)); } \
    friend class Class##Private;

#define Q_DECLARE_PUBLIC(Class)                                    \
    inline Class* q_func() { return static_cast<Class *>(q_ptr); } \
    inline const Class* q_func() const { return static_cast<const Class *>(q_ptr); } \
    friend class Class;

对于QComboBox来说,Q_D(const QComboBox)相当于是:

QComboBoxPrivate *const d = reinterpret_cast<QComboBoxPrivate *>(qGetPtrHelper(d_ptr));

Q_Q(QComboBox) 相当于是:

QComboBox *const q = static_cast<const Class *>(q_ptr);

d_prt定义在:

class Q_CORE_EXPORT QObject
{
    Q_OBJECT
    Q_PROPERTY(QString objectName READ objectName WRITE setObjectName NOTIFY objectNameChanged)
    Q_DECLARE_PRIVATE(QObject)

    /* 此处省略其余定义 */
protected:
    QScopedPointer<QObjectData> d_ptr;

d_ptr是在:

QComboBox::QComboBox(QWidget *parent)
    : QWidget(*new QComboBoxPrivate(), parent, 0)
{
    Q_D(QComboBox);
    d->init();
}

这里new QComboBoxPrivate(),一层一层地往下传递,最后会传递到:

QObject::QObject(QObjectPrivate &dd, QObject *parent)
    : d_ptr(&dd)
{
    Q_D(QObject);
    d_ptr->q_ptr = this;
.....
}

这里QObjectd::d_ptr就值了。dptr->q_ptr保存了当前控件的this指针。因为QComboBoxPrivate继承QWidgetPrivate,QWidgetPrivate继承QObjectPrivate,QObjectPrivate继承 QObjectData, QObjectData的定义如下:

class Q_CORE_EXPORT QObjectData {
public:
    virtual ~QObjectData() = 0;
    QObject *q_ptr;
    QObject *parent;
    QObjectList children;

    uint isWidget : 1;
    uint blockSig : 1;
    uint wasDeleted : 1;
    uint isDeletingChildren : 1;
    uint sendChildEvents : 1;
    uint receiveChildEvents : 1;
    uint isWindow : 1; //for QWindow
    uint unused : 25;
    int postedEvents;
    QDynamicMetaObjectData *metaObject;
    QMetaObject *dynamicMetaObject() const;
};

回到上文,

Q_D(const QComboBox)相当于是:

QComboBoxPrivate *const d = reinterpret_cast<QComboBoxPrivate *>(qGetPtrHelper(d_ptr));

也就是将d_ptr转换成具体的QComboBoxPrivate类,控件的数据都保存在它对应的Private类里,例如QComboBox的数据都保存在:

class Q_AUTOTEST_EXPORT QComboBoxPrivate : public QWidgetPrivate
{
    Q_DECLARE_PUBLIC(QComboBox)
public:
    QComboBoxPrivate();
    ~QComboBoxPrivate();
    void init();
    /* 此处省略相关声明 */

#ifdef Q_OS_MAC
    void cleanupNativePopup();
    bool showNativePopup();
#endif

    QAbstractItemModel *model;
    QLineEdit *lineEdit;
    QComboBoxPrivateContainer *container;
    QComboBox::InsertPolicy insertPolicy;
    QComboBox::SizeAdjustPolicy sizeAdjustPolicy;
    int minimumContentsLength;
    QSize iconSize;
    /* 此处省略相关声明 */
    static QPalette viewContainerPalette(QComboBox *cmb)
    { return cmb->d_func()->viewContainer()->palette(); }
};

QComboBox需要访问数据时,先通过Q_D,将d_ptr转换成QComboBoxPrivate的指针,再访问数据;

而QComboBoxPrivate需要访问QComboBox的接口时,先通过Q_Q,将q_ptr转换成QComboBox指针,再调用QComboBox的接口;

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值