设计模式之代理模式
我们使用Qt开发大型应用程序时,经常遇见大型程序启动时需要加载一些配置信息、用户末次操作信息,以及算法模型等数据时比较费时,笔者在程序启动时设计欢迎页或加载页等窗体来提示用户程序正在加载某些数据,加载界面运行的时候使用代理模式去读取程序运行所需的数据。
- 效果演示
- 代码
cpp
#ifndef CONFIGUREBRIDGE_H
#define CONFIGUREBRIDGE_H
#include <QObject>
#pragma pack(push)
#pragma pack(1)
typedef struct s_DataBaseInfo
{
QString _ip;
qint16 _port;
QString _userName;
QString _pwd;
QString _dbName;
qint32 _saveMark;
qint32 _logMark;
}DataBaseInfo;
#pragma pack(pop)
class ConfigureBridge : public QObject
{
Q_OBJECT
public:
static ConfigureBridge *Instance();
static void Destroy();
private:
explicit ConfigureBridge(QObject *parent = nullptr);
ConfigureBridge(const ConfigureBridge &);
ConfigureBridge &operator=(const ConfigureBridge &);
~ConfigureBridge();
private:
static ConfigureBridge* _instance;
signals:
public:
DataBaseInfo g_DBInfo;
};
Q_DECLARE_METATYPE(DataBaseInfo)
#endif // CONFIGUREBRIDGE_H
//-----------------------------
#include "configurebridge.h"
ConfigureBridge* ConfigureBridge::_instance = nullptr;
ConfigureBridge *ConfigureBridge::Instance()
{
if(_instance == nullptr)
{
_instance = new ConfigureBridge();
}
return _instance;
}
void ConfigureBridge::Destroy()
{
if(_instance != nullptr)
{
delete _instance;
_instance = nullptr;
}
}
ConfigureBridge::ConfigureBridge(QObject *parent) : QObject(parent)
{
}
ConfigureBridge::ConfigureBridge(const ConfigureBridge &)
{
}
ConfigureBridge &ConfigureBridge::operator=(const ConfigureBridge &)
{
}
ConfigureBridge::~ConfigureBridge()
{
}
cpp
#ifndef LOADDATA_H
#define LOADDATA_H
#include <QObject>
#include <QFile>
#include <QXmlStreamReader>
// 系统配置文件XML
class ReadXml : public QObject
{
Q_OBJECT
public:
explicit ReadXml(QObject *parent = nullptr);
void readSysCfg();
};
class OP_Subject
{
public:
virtual void readOperatePointsData() = 0;
};
// 工况点数据Dat
class LoadData : public QObject, public OP_Subject
{
Q_OBJECT
public:
explicit LoadData(QObject *parent = nullptr);
void readOperatePointsData() override;
signals:
};
class OP_Proxy : public QObject, public OP_Subject
{
Q_OBJECT
public:
explicit OP_Proxy(QObject *parent = nullptr);
void readOperatePointsData() override;
private:
LoadData* m_loadData;
};
#endif // LOADDATA_H
//--------------------------------
#include "loaddata.h"
#include <QDataStream>
#include <QDebug>
#include <QTextCodec>
#include <unistd.h>
#include "configurebridge.h"
ReadXml::ReadXml(QObject *parent) : QObject(parent)
{
}
void ReadXml::readSysCfg()
{
printf("[%s:%s:%d]\n", __FILE__, __FUNCTION__, __LINE__);
QFile file("system_config.xml");
if(!file.open(QIODevice::ReadOnly | QIODevice::Text))
{
return;
}
QXmlStreamReader xmlReader(&file);
if(xmlReader.hasError())
{
qDebug() << "XML error: " << xmlReader.errorString();
return;
}
while (!xmlReader.atEnd() && !xmlReader.hasError())
{
xmlReader.readNext();
if(xmlReader.isStartElement())
{
// qDebug() << xmlReader.name().toString();
if(xmlReader.name().toString() == "ip")
{
QString item = xmlReader.readElementText();
qDebug() << item;
ConfigureBridge::Instance()->g_DBInfo._ip = item;
}
else if(xmlReader.name().toString() == "port")
{
QString item = xmlReader.readElementText();
qDebug() << item;
ConfigureBridge::Instance()->g_DBInfo._port = item.toUInt();
}
else if(xmlReader.name().toString() == "username")
{
QString item = xmlReader.readElementText();
qDebug() << item;
ConfigureBridge::Instance()->g_DBInfo._userName = item;
}
else if(xmlReader.name().toString() == "pwd")
{
QString item = xmlReader.readElementText();
qDebug() << item;
ConfigureBridge::Instance()->g_DBInfo._pwd = item;
}
else if(xmlReader.name().toString() == "dbname")
{
QString item = xmlReader.readElementText();
qDebug() << item;
ConfigureBridge::Instance()->g_DBInfo._dbName = item;
}
else if(xmlReader.name().toString() == "save_mark")
{
QString item = xmlReader.readElementText();
qDebug() << item;
ConfigureBridge::Instance()->g_DBInfo._saveMark = item.toInt();
}
else if(xmlReader.name().toString() == "log_mark")
{
QString item = xmlReader.readElementText();
qDebug() << item;
ConfigureBridge::Instance()->g_DBInfo._logMark = item.toInt();
}
}
else if(xmlReader.isEndElement())
{
// qDebug() << "==End==";
}
else if(xmlReader.isCharacters() && !xmlReader.isWhitespace())
{
// qDebug() << xmlReader.text().toString();
}
}
file.close();
}
LoadData::LoadData(QObject *parent) : QObject(parent)
{
}
void LoadData::readOperatePointsData()
{
printf("[%s:%s:%d]\n", __FILE__, __FUNCTION__, __LINE__);
sleep(2);
QFile file("op_info.dat");
if(!file.open(QIODevice::ReadOnly))
{
return;
}
QString strBinary;
QTextCodec* codec = QTextCodec::codecForName("UTF-8");
QDataStream dataStream(&file);
while (!dataStream.atEnd())
{
QByteArray tmpLine = file.readLine();
strBinary += codec->toUnicode(tmpLine.trimmed());
}
file.close();
qDebug() << strBinary;
sleep(2);
qDebug() << "Data loading completed ^_^";
}
OP_Proxy::OP_Proxy(QObject *parent) : QObject(parent)
{
m_loadData = nullptr;
}
void OP_Proxy::readOperatePointsData()
{
printf("[%s:%s:%d]\n", __FILE__, __FUNCTION__, __LINE__);
if(m_loadData == nullptr)
{
m_loadData = new LoadData();
}
m_loadData->readOperatePointsData();
}
cpp
#ifndef SYSTEMCONFIG_H
#define SYSTEMCONFIG_H
#include <QObject>
#include "welcomefrm.h"
#include "loaddata.h"
/**
* 1、加载系统配置信息
* 2、加载工况点数据
*/
class SystemConfig : public QObject
{
Q_OBJECT
public:
explicit SystemConfig(QObject *parent = nullptr);
void read_system_config();
void closeWelPage();
signals:
private:
WelcomeFrm* m_welFrm;
ReadXml* m_readXmlCfg;
OP_Proxy* m_opProxy;
};
#endif // SYSTEMCONFIG_H
//--------------------------------------
#include "systemconfig.h"
#include <QCoreApplication>
SystemConfig::SystemConfig(QObject *parent) : QObject(parent)
{
m_welFrm = new WelcomeFrm();
m_readXmlCfg = new ReadXml(this);
m_opProxy = new OP_Proxy(this);
}
void SystemConfig::read_system_config()
{
m_welFrm->show();
QCoreApplication::processEvents();
m_readXmlCfg->readSysCfg();
m_opProxy->readOperatePointsData();
}
void SystemConfig::closeWelPage()
{
m_welFrm->hide();
m_welFrm->deleteLater();
m_welFrm = nullptr;
}
cpp
#ifndef WELCOMEFRM_H
#define WELCOMEFRM_H
#include <QWidget>
namespace Ui {
class WelcomeFrm;
}
class WelcomeFrm : public QWidget
{
Q_OBJECT
public:
explicit WelcomeFrm(QWidget *parent = nullptr);
~WelcomeFrm();
void initSystemCfg();
private:
Ui::WelcomeFrm *ui;
};
#endif // WELCOMEFRM_H
//------------------------------------
#include "welcomefrm.h"
#include "ui_welcomefrm.h"
#include <QPalette>
#include <QPixmap>
WelcomeFrm::WelcomeFrm(QWidget *parent) :
QWidget(parent),
ui(new Ui::WelcomeFrm)
{
ui->setupUi(this);
//去掉窗口边框
this->setWindowFlags(Qt::X11BypassWindowManagerHint | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint);
QPalette pal = this->palette();
pal.setBrush(QPalette::Background, QBrush(QPixmap(":/res/welcome.jpg")));
setPalette(pal);
ui->label->setStyleSheet("QLabel{color: rgb(255,0,255);"
"border: 1px solid green; border-radius: 2px;"
"font-size: 30px; font-weight:bold;}");
ui->label->setText("数据加载中...");
printf("[%s:%s:%d]\n", __FILE__, __FUNCTION__, __LINE__);
}
WelcomeFrm::~WelcomeFrm()
{
delete ui;
}
void WelcomeFrm::initSystemCfg()
{
}
cpp
#ifndef MAINWIDGET_H
#define MAINWIDGET_H
#include <QWidget>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWidget; }
QT_END_NAMESPACE
class MainWidget : public QWidget
{
Q_OBJECT
public:
MainWidget(QWidget *parent = nullptr);
~MainWidget();
private:
Ui::MainWidget *ui;
};
#endif // MAINWIDGET_H
//--------------------------------
#include "mainwidget.h"
#include "ui_mainwidget.h"
#include "configurebridge.h"
#include <QDebug>
MainWidget::MainWidget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::MainWidget)
{
ui->setupUi(this);
ui->textEdit->setReadOnly(true);
ui->textEdit->setStyleSheet("QTextEdit{background: #033441;"
"color:#64eefa;"
"border:1px solid #64eefa;"
"font-size: 30px;"
"font-weight:bold;}");
ui->textEdit->append(ConfigureBridge::Instance()->g_DBInfo._ip);
ui->textEdit->append(QString::number(ConfigureBridge::Instance()->g_DBInfo._port));
ui->textEdit->append(ConfigureBridge::Instance()->g_DBInfo._userName);
ui->textEdit->append(ConfigureBridge::Instance()->g_DBInfo._pwd);
ui->textEdit->append(ConfigureBridge::Instance()->g_DBInfo._dbName);
ui->textEdit->append(QString::number(ConfigureBridge::Instance()->g_DBInfo._saveMark));
ui->textEdit->append(QString::number(ConfigureBridge::Instance()->g_DBInfo._logMark));
}
MainWidget::~MainWidget()
{
delete ui;
}
cpp
#include <QApplication>
#include <QElapsedTimer>
#include <QMetaType>
#include <unistd.h>
#include "configurebridge.h"
#include "systemconfig.h"
#include "mainwidget.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
qRegisterMetaType<DataBaseInfo>("DataBaseInfo");
// 加载系统的配置数据
SystemConfig sysCfg;
sysCfg.read_system_config();
MainWidget w;
w.show();
sysCfg.closeWelPage();
return a.exec();
}