Qt——自定义二进制兼容(d/q指针)的类实现继承笔记

d/q指针的原理

参考链接
维基百科上讲得很详细,故不再进行赘述。

关于为什么写这篇文章

最近因为自定义输入框,采用了d/p指针来实现二进制兼容。在参考官方例子,也就是上面的参考链接时,始终都无法实现。一直报错无法调用已删除函数。最后实在没有办法去查阅Qt源码,参考了QLineEdit本身的实现,发现了是因为没有给Private加默认构造函数构成的。

为什么类的数据类要以Private结尾?

这是因为Q_D宏定义的

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

一个具体的例子的描述

  1. 定义一个类LineEdit,继承于QLineEdit;
  2. 定义一个子类,继承于LineEdit;

具体代码实现

lineedit_p.h

#ifndef LINEEDIT_P_H
#define LINEEDIT_P_H

#include <QObject>
class LineEdit;
class LineEditPrivate{

    Q_DECLARE_PUBLIC(LineEdit)
public:

    LineEditPrivate(){}
    ~LineEditPrivate(){}

    LineEditPrivate(LineEdit *parent):
        q_ptr(parent){}

    //data
    QString tipText;
    QRegExp regExp;

protected:
    LineEdit * q_ptr;
};

#endif // LINEEDIT_P_H

lineedit.h

#ifndef LINEEDIT_H
#define LINEEDIT_H

#include <QLineEdit>
#include <QFocusEvent>

class QRegExp;

class LineEditPrivate;

class LineEdit:public QLineEdit
{
    Q_OBJECT
public:
    explicit LineEdit(QWidget *parent=nullptr);
    virtual ~LineEdit();

    void setRegExp(const QRegExp &regExp);
    void setTipText(const QString &text);
    void clearRegExp();
signals:
    void verificationResult(bool,QString);
protected:
    void updateValidator();
    void focusOutEvent(QFocusEvent *pEvent);

    LineEdit(LineEditPrivate &d,QWidget *parent=nullptr);

    LineEditPrivate * d_ptr;
private:
    Q_DECLARE_PRIVATE(LineEdit)
    Q_DISABLE_COPY(LineEdit)

};

#endif // LINEEDIT_H

lineedit.cpp

#include "lineedit.h"

#include <QRegExp>
#include <QRegExpValidator>

#include "lineedit_p.h"

LineEdit::LineEdit(QWidget *parent):
    QLineEdit(parent),
    d_ptr(new LineEditPrivate(this))
{

}

LineEdit::~LineEdit()
{
    Q_D(LineEdit);

    delete d;
}

void LineEdit::setRegExp(const QRegExp &regExp)
{
    Q_D(LineEdit);
    d->regExp = regExp;
}

void LineEdit::setTipText(const QString &text)
{
    Q_D(LineEdit);
    d->tipText = text;
}

void LineEdit::clearRegExp()
{
    Q_D(LineEdit);
    d->regExp.setPattern("");
}

void LineEdit::focusOutEvent(QFocusEvent *pEvent)
{
    Q_D(LineEdit);

    if(!d->regExp.exactMatch(this->text())){
        this->setStyleSheet("QLineEdit{border:1px solid red }");
        emit verificationResult(false,d->tipText);
    }else{
        this->setStyleSheet("QLineEdit{border:1px solid gray border-radius:1px}");
        emit verificationResult(true,"");
    }

    QLineEdit::focusOutEvent(pEvent);
}

LineEdit::LineEdit(LineEditPrivate &d, QWidget *parent):
    d_ptr(&d),
    QLineEdit(parent)
{

}

intedit.h

#ifndef INTEDIT_H
#define INTEDIT_H

#include "lineedit.h"

class IntEditPrivate;

class IntEdit:public LineEdit
{
    Q_OBJECT
public:
    explicit IntEdit(QWidget *parent=nullptr);
    virtual ~IntEdit();

protected:

private:
    Q_DECLARE_PRIVATE(IntEdit)
};

#endif // INTEDIT_H

intedit.cpp

#include "intedit.h"

#include "lineedit_p.h"

class IntEditPrivate:public LineEditPrivate{
    Q_DECLARE_PUBLIC(IntEdit)
public:
    IntEditPrivate(){}
    ~IntEditPrivate(){}

    QString test;
};

IntEdit::IntEdit(QWidget *parent):
    LineEdit(*new IntEditPrivate,parent)
{
    Q_D(IntEdit);
    d->test = "AAA";
}

IntEdit::~IntEdit()
{

}
发布了28 篇原创文章 · 获赞 4 · 访问量 7380

猜你喜欢

转载自blog.csdn.net/JuicyActiveGilbert/article/details/103904318
今日推荐