Qt的pimpl模式,和Bridge模式用法和例子

为了兼容二进制,为了更好抽象类,为了以后代码的维护性和可扩展性,用到PIMPL模式,C++的PIMPL模式与Qt有些不一样.
此模式下两个类:公有的类,和XXXXPrivate私有
同时这个例子说明了qt的当前目录,以及qt如何在硬盘中载入图片并且在lebel中设定图片并且显示;
下面是简单例子:



PIMPL公有类,头文件;

    #ifndef PIMPL_H
    #define PIMPL_H

    #include <QObject>
    #include "QPixmap"


    class PimplPrivate;

    class Pimpl : public QObject
    {
        Q_OBJECT
    public:
        explicit Pimpl(QObject *parent = 0);
        Pimpl *instance();//返回一个实例指针

        void test_printf_demo();//测试函数,这个类的一个方法
        QPixmap load_pic(QString &path);
        char* getCurrentWorkingPath(void);
    signals:

    public slots:

    private:
        static Pimpl *self;//这个是类的实例句柄,在实现的cpp文件中,需要声明为NULL,例如Pimpl *Pimpl::self = NULL;
    private:
        int test_a;
        PimplPrivate * const d_ptr;//在公有接口类中定义一个私有的,只读的d_ptr,名字必须是d_ptr

        Q_DECLARE_PRIVATE(Pimpl)//在公有接口的类中,需要private,无论哪个DECLARE都是公有类,只是private和public的区别
    };

    #endif // PIMPL_H


pimpl实现文件

    #include "stdio.h"//包含各个标准头文件,文件操作头文件
    #include "stdlib.h"
    #include "direct.h"

    #include "pimpl.h"
    #include "pimplprivate.h"
    #include "QImage"
    #include "QPixmap"
    #include "qdebug.h"
    #include "qdir.h"


    Pimpl *Pimpl::self = NULL;//注意,这里要定义,不然编译不过

    Pimpl::Pimpl(QObject *parent) : QObject(parent),
        d_ptr(new PimplPrivate(this))//构造的时候,初始化d_ptr
    {
        qDebug("Current: %s", getCurrentWorkingPath());
    }

    Pimpl *Pimpl::instance()//返回实例,可以用到单例模式
    {
        Q_ASSERT(self);//返回实例,qt单例模式,C++单例模式
        return self;
    }



    void Pimpl::test_printf_demo()
    {
        d_ptr->test_b = 0;//bridge模式,pimpl模式访问私有类的内容
        qDebug("This is a printf of PIMPL Mode!");
        d_ptr->test_pimlePrivate_printf_demo();//私有类private类的函数

    }

    QPixmap Pimpl::load_pic(QString &path)//qt载入图片,QImage加载图片,qt加载图片
    {
       return d_ptr->load_pic_form_path(path);//二进制兼容,qt桥接模式,qt pimpl模式
    }

    char *Pimpl::getCurrentWorkingPath(void)
    {
        char* pPWDBuffer = NULL;
        if( (pPWDBuffer = _getcwd( NULL, 0 )) == NULL ) {
            qDebug( "_getcwd error" );
        } else {
            qDebug( "Current Dir: %s\n", pPWDBuffer);//QT当前路径qt获取当前路径例子
            free(pPWDBuffer);
        }
        qDebug()<< "Qt Current Path:" << QDir::currentPath();//qt获取当前路径例子。注意当前路径不是程序所在路径!而是上一级,编译目录!
        return pPWDBuffer;
    }


PIMPL中的私有类头文件,private,公开的Pimpl的类可以通过d_ptr访问此类;


    #ifndef PIMPLPRIVATE_H
    #define PIMPLPRIVATE_H

    #include "pimpl.h"
    #include "QPixmap"
    #include "QRect"

    class PimplPrivate
    {
    public:
        PimplPrivate(Pimpl *parent);//构造函数,记得构造函数里传入pimpl
        void test_pimlePrivate_printf_demo();//这个私有类的测试函数
        QPixmap load_pic_form_path(QString &path);
    private:
        QPixmap testPixmap;
        int test_b;//测试的变量,返回私有成员测试
        Pimpl * const q_ptr;//qptr是访问上层的公有类的指针,必须叫q_ptr;
        Q_DECLARE_PUBLIC(Pimpl)//在私有的类中,需定义public了
    };


    #endif // PIMPLPRIVATE_H


    #include "pimplprivate.h"
    #include "qpixmap.h"

    PimplPrivate::PimplPrivate(Pimpl *parent)://在pivate里面,传入部分是的Pimpl类指针
        q_ptr(parent)//初始哈的时候,需要初始化q_ptr,传入parent
    {

    }


    void PimplPrivate::test_pimlePrivate_printf_demo()//私有函数,private里面的函数可以随意增加删减,通过q_ptr可以访问公有部分。
    {
        q_ptr->test_a = 0;
        qDebug("This is PIMPL mode, in private class!");
    }

    QPixmap PimplPrivate::load_pic_form_path(QString &path)
    {
        QImage tmpImage;
        if(false == tmpImage.load(path)){
            qDebug("[%s]%d: load Image failed!", __FUNCTION__, __LINE__);//qt调试函数名,qt调试函数打印
            return NULL;
        }else{
            return QPixmap::fromImage(tmpImage);//返回Qpixmap,qt返回label图片,qt返回图片
        }
    }


使用方法,主文件,main.c:

    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);

        MainWindow *w = new MainWindow();
        Pimpl *p = new Pimpl;

        p->test_printf_demo();

        QString picPath(".\\1.png");//qt相对路径,注意,不是应用程序的路径,而是向上一级的路径
        QPixmap myPixmap = p->load_pic(picPath);
        w->setUiLabelPicture(myPixmap);//laebel载入图片,图片label显示在图片上,qt载入图片例子
        w->setUiLabelPictureWidthAndHight(myPixmap.rect());//设定label大小,刚刚适合图片大小;
        w->show();

        return a.exec();
    }

这其实就是QT的d_ptr和q_ptr大法。请注意注释

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mynameislinduan

你的鼓励是我最大动力写博客不易

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值