为了兼容二进制,为了更好抽象类,为了以后代码的维护性和可扩展性,用到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大法。请注意注释