QT-自定义参数设计框架软件
前言
常用本地数据参数通常使用的是xml等文本的格式,进行本地的数据参数的存储。这种参数的保存方式有个致命的一点,就是可以存在参数的丢失。特别是在软件异常退出的情况下发生。
针对此等情况,我们现在使用的是sqllite的本地存储方式进行设计,并且尽量将参数的格式通用化。
一、演示效果
二、使用步骤
1.应用进行参数注册
代码如下:
c
void QSettingTools::registerParams()
{
if (1)
{
QString strGroupName = u8"用户参数";
cParamOperator::getInstance()->registerQString(strGroupName, "User", "sa", QString(u8"用户名称"));
cParamOperator::getInstance()->registerQString(strGroupName, "Passord", "123456", QString(u8"用户密码"));
cParamOperator::getInstance()->registerInt(strGroupName, "Index", 0, 0, 10000, QString(u8"序号"));
cParamOperator::getInstance()->registerFloat(strGroupName, "Time", 1.5, 0, 10000, QString(u8"时间,单位秒"));
}
if (1)
{
QString strGroupName = u8"系统参数";
cParamOperator::getInstance()->registerQString(strGroupName, "FactoryId", "123433ad", QString(u8"工厂ID"));
}
cParamOperator::getInstance()->autoRemoveInvialParams();
}
2.数据库操作单例对象
代码如下:
c
#include "ParamOperator.h"
#include "SqlLiteDatabase.h"
#include <QFile>
#include <QMutex>
#include <QXmlStreamWriter>
#include <QDebug>
#include <QCoreApplication>
#include <QDomDocument>
#include <QApplication>
cParamOperator g_userParam; // 用户参数
struct cAppBaserData
{
QHash<QString, QString> strScrTranHash;
};
cParamOperator::cParamOperator()
: d_ptr(new cParamManagerData)
{
m_strConfig = "Setting.db";
}
cParamOperator::~cParamOperator()
{
delete d_ptr;
d_ptr = nullptr;
}
// 获取一个实例
cParamOperator *cParamOperator::getInstance()
{
static cParamOperator manager;
return &manager;
}
// 设置app安装目录
void cParamOperator::setAppExePath(QString strPath)
{
m_strAppExePath = strPath;
cSqlLiteDatabase::getInstance()->setAppExePath(strPath);
initialParams();
}
// 注册整形参数
void cParamOperator::registerInt(QString strGroup, QString strName, int nMin, int nSet, int nMax, QString strDescribe)
{
sParamItem_t paramItem;
paramItem.strGroupName = strGroup;
paramItem.strParamType = PARAM_TYPE_INT;
paramItem.strName = strName;
paramItem.strDescribe = strDescribe;
paramItem.minVal = nMin;
paramItem.setVal = nSet;
paramItem.maxVal = nMax;
registerParam(paramItem);
}
// 注册浮点型参数
void cParamOperator::registerFloat(QString strGroup, QString strName, float fMin, float fSet, float fMax, QString strDescribe)
{
sParamItem_t paramItem;
paramItem.strGroupName = strGroup;
paramItem.strParamType = PARAM_TYPE_FLOAT;
paramItem.strName = strName;
paramItem.strDescribe = strDescribe;
paramItem.minVal = fMin;
paramItem.setVal = fSet;
paramItem.maxVal = fMax;
registerParam(paramItem);
}
// 注册字符串参数
void cParamOperator::registerQString(QString strGroup, QString strName, QString strSet, QString strDescribe)
{
sParamItem_t paramItem;
paramItem.strGroupName = strGroup;
paramItem.strParamType = PARAM_TYPE_STRING;
paramItem.strName = strName;
paramItem.strDescribe = strDescribe;
paramItem.minVal = "";
paramItem.setVal = strSet;
paramItem.maxVal = "";
registerParam(paramItem);
}
// 修改参数值
void cParamOperator::setParam(QString strName, QVariant var)
{
auto pParam = getParam(strName);
if (pParam != nullptr)
{
pParam->setVal = var;
g_userParam.updateParam(*pParam);
}
}
// 获取整数
int cParamOperator::getParamInt(QString strName)
{
auto param = getParam(strName);
if (param != nullptr)
{
return param->setVal.toInt();
}
return -12345;
}
// 获取浮点数
float cParamOperator::getParamFloat(QString strName)
{
auto param = getParam(strName);
if (param != nullptr)
{
return param->setVal.toFloat();
}
return -12345;
}
// 获取字符串
QString cParamOperator::getParamString(QString strName)
{
auto param = getParam(strName);
if (param != nullptr)
{
return param->setVal.toString();
}
return "Error";
}
// 获取参数组名链表
QStringList cParamOperator::getGroupNameList()
{
QStringList strNameList;
auto paramList = params();
for (size_t i = 0; i < paramList->size(); i++)
{
auto item = paramList->at(i);
if (!strNameList.contains(item.strGroupName))
{
strNameList << item.strGroupName;
}
}
return strNameList;
}
// 获取某个组的所有参数
QVector<sParamItem_t> cParamOperator::getGroupParam(QString strGroupName)
{
QVector<sParamItem_t> list;
auto paramList = params();
for (size_t i = 0; i < paramList->size(); i++)
{
auto item = paramList->at(i);
if (item.strGroupName == strGroupName)
{
list << item;
}
}
return list;
}
// 初始化一个参数,插入内存中
int cParamOperator::initialParamItem(sParamItem_t ¶m)
{
// 注册过的就直接返回就行了
if (d_ptr->mapName.contains(param.strName))
return d_ptr->mapName.value(param.strName);
// 链表没有,插入链表记录
auto index = d_ptr->vecParam.count();
d_ptr->vecParam.append(param);
d_ptr->mapName.insert(param.strName, index);
// 如果有组名,直接插入到组名对应得链表里面
if (d_ptr->mapGroup.contains(param.strGroupName))
{
for (auto iter = d_ptr->mapGroup.begin(); iter != d_ptr->mapGroup.end(); iter++)
{
if (iter.key() == param.strGroupName)
{
iter.value().insert(param.strName, index);
break;
}
}
}
else
{
// 重新建立一个组名链表
QHash<QString, int> groupItem;
groupItem.insert(param.strName, index);
d_ptr->mapGroup.insert(param.strGroupName, groupItem);
}
return index;
}
// 刷新参数
bool cParamOperator::updateParam(sParamItem_t ¶m, bool bUpdateAll)
{
bool bRet = false;
if (!param.strName.isEmpty())
{
if (bUpdateAll)
{
// 整个项都更新
cSqlLiteDatabase::getInstance()->update(d_ptr->strTableName, g_strTagName, param.strName, g_strTagSetVal, param.setVal.toString());
cSqlLiteDatabase::getInstance()->update(d_ptr->strTableName, g_strTagName, param.strName, g_strTagGroupName, param.strGroupName);
cSqlLiteDatabase::getInstance()->update(d_ptr->strTableName, g_strTagName, param.strName, g_strTagType, param.strParamType);
cSqlLiteDatabase::getInstance()->update(d_ptr->strTableName, g_strTagName, param.strName, g_strTagMinVal, param.minVal.toString());
cSqlLiteDatabase::getInstance()->update(d_ptr->strTableName, g_strTagName, param.strName, g_strTagMaxVal, param.maxVal.toString());
}
else
{
cSqlLiteDatabase::getInstance()->update(d_ptr->strTableName, g_strTagName, param.strName, g_strTagSetVal, param.setVal.toString());
}
}
return bRet;
}
// 通过参数名获取参数
sParamItem_t *cParamOperator::getParam(QString strName)
{
return getParam(d_ptr->mapName.value(strName, -1));
}
// 通过索引获取参数
sParamItem_t *cParamOperator::getParam(int nIndex)
{
if (nIndex >= 0 && nIndex < d_ptr->vecParam.count())
return &d_ptr->vecParam[nIndex];
return nullptr;
}
// 所有的参数
QVector<sParamItem_t>* cParamOperator::params()
{
return &d_ptr->vecParam;
}
// 删除参数
bool cParamOperator::removeParam(QString strName)
{
for (int i = 0; i < d_ptr->vecParam.size(); i++)
{
if (d_ptr->vecParam[i].strName == strName)
{
d_ptr->vecParam.removeAt(i);
break;
}
}
return cSqlLiteDatabase::getInstance()->remove(m_strTableName, g_strTagName, strName);
}
// 注册参数
int cParamOperator::registerParam(sParamItem_t ¶m)
{
// 缓存起来
if (!m_strResisterNameList.contains(param.strName))
m_strResisterNameList << param.strName;
// 注册过,组名不同得话就重新修改所属得组名,如果没有就直接返回
if (d_ptr->mapName.contains(param.strName))
{
auto paramTemp = getParam(param.strName);
// 如果组名不同,就换新注册得组名
if (paramTemp->strGroupName != param.strGroupName)
{
auto itGroup = d_ptr->mapGroup.find(paramTemp->strGroupName);
if (itGroup != d_ptr->mapGroup.end())
{
// 删掉旧的,再插入新得
auto qTempHash = itGroup.value();
d_ptr->mapGroup.erase(itGroup);
d_ptr->mapGroup.insert(param.strGroupName, qTempHash);
}
// 更新为最新注册得
paramTemp->strGroupName = param.strGroupName;
cSqlLiteDatabase::getInstance()->update(d_ptr->strTableName, g_strTagName, param.strName, g_strTagGroupName, param.strGroupName);
}
cSqlLiteDatabase::getInstance()->update(d_ptr->strTableName, g_strTagName, param.strName, g_strTagMinVal, param.minVal.toString());
cSqlLiteDatabase::getInstance()->update(d_ptr->strTableName, g_strTagName, param.strName, g_strTagMaxVal, param.maxVal.toString());
auto pItem = getParam(param.strName);
if (pItem != nullptr)
{
pItem->strDescribe = param.strDescribe;
pItem->minVal = param.minVal;
pItem->maxVal = param.maxVal;
if (pItem->strDescribe.indexOf("《****")!= -1)
{
param.strRemarks = "";
}
pItem->strRemarks = param.strRemarks;
}
return d_ptr->mapName.value(param.strName);
}
// 链表没有,插入链表记录
auto index = d_ptr->vecParam.count();
d_ptr->vecParam.append(param);
d_ptr->mapName.insert(param.strName, index);
QHash<QString, QString> itemHash;
// 同时插入数据表
itemHash.insert(g_strTagGroupName, param.strGroupName);
itemHash.insert(g_strTagType, param.strParamType);
itemHash.insert(g_strTagName, param.strName);
itemHash.insert(g_strTagSetVal, param.setVal.toString());
itemHash.insert(g_strTagMinVal, param.minVal.toString());
itemHash.insert(g_strTagMaxVal, param.maxVal.toString());
itemHash.insert(g_strTagDescribe, param.strDescribe);
cSqlLiteDatabase::getInstance()->insert(d_ptr->strTableName,itemHash);
// 如果有组名,直接插入到组名对应得链表里面
if (d_ptr->mapGroup.contains(param.strGroupName))
{
for (auto iter = d_ptr->mapGroup.begin(); iter != d_ptr->mapGroup.end(); iter++)
{
if (iter.key() == param.strGroupName)
{
iter.value().insert(param.strName, index);
break;
}
}
}
else
{
// 重新建立一个组名链表
QHash<QString, int> groupItem;
groupItem.insert(param.strName, index);
d_ptr->mapGroup.insert(param.strGroupName, groupItem);
}
return index;
}
// 全部注册后,删除无效参数(注意:所有的参数要全部注册完成后调用)
void cParamOperator::autoRemoveInvialParams()
{
for (auto itSqlName:m_strSqlParamNameList)
{
// 如果程序注册的链表不存在就需要删除数据库的参数
if (!m_strResisterNameList.contains(itSqlName))
{
removeParam(itSqlName);
}
}
// 重新排序,按注册顺序显示
QVector<sParamItem_t> tempAllParam = d_ptr->vecParam;
d_ptr->vecParam.clear();
d_ptr->mapName.clear();
d_ptr->mapGroup.clear();
for (auto itRegister:m_strResisterNameList)
{
for (auto& itFind : tempAllParam)
{
if (itFind.strName == itRegister)
{
initialParamItem(itFind);
break;
}
}
}
}
// 初始化数据参数
int cParamOperator::initialParams(QString strTableName)
{
if (strTableName.isEmpty())
return -1;
// 先打开数据库
cSqlLiteDatabase::getInstance()->openDb(m_strConfig);
m_strTableName = strTableName;
static QMutex mutex;
mutex.lock();
// 创建数据库表
QStringList strList;
strList << g_strTagGroupName << g_strTagType
<< g_strTagName << g_strTagSetVal
<< g_strTagMinVal << g_strTagMaxVal
<< g_strTagDescribe << g_strTagIsTemp;
d_ptr->strTableName = strTableName;
cSqlLiteDatabase::getInstance()->createTable(strTableName, strList);
// 查找数据库表的所有参数
auto dataHashList = cSqlLiteDatabase::getInstance()->select(strTableName);
for (int i = 0; i < dataHashList.size(); i++)
{
auto hash = dataHashList[i];
sParamItem_t paramItem;
paramItem.strGroupName = hash.find(g_strTagGroupName) != hash.end() ? hash.find(g_strTagGroupName).value() : "";
paramItem.strParamType = hash.find(g_strTagType) != hash.end() ? hash.find(g_strTagType).value() : "";
paramItem.strName = hash.find(g_strTagName) != hash.end() ? hash.find(g_strTagName).value() : "";
paramItem.setVal = hash.find(g_strTagSetVal) != hash.end() ? hash.find(g_strTagSetVal).value() : "";
paramItem.minVal = hash.find(g_strTagMinVal) != hash.end() ? hash.find(g_strTagMinVal).value() : "";
paramItem.maxVal = hash.find(g_strTagMaxVal) != hash.end() ? hash.find(g_strTagMaxVal).value() : "";
paramItem.strDescribe = hash.find(g_strTagDescribe) != hash.end() ? hash.find(g_strTagDescribe).value() : "";
// 缓存数据库的参数名称
if (!m_strSqlParamNameList.contains(paramItem.strName))
m_strSqlParamNameList << paramItem.strName;
initialParamItem(paramItem);
}
mutex.unlock();
return 0;
}
3.参数操作单例对象
代码如下:
cpp
#include "SqlLiteDatabase.h"
#include <QDir>
#include <QDateTime>
#include <QApplication>
cSqlLiteDatabase::cSqlLiteDatabase(QObject *parent)
: QObject(parent)
{
}
cSqlLiteDatabase::~cSqlLiteDatabase()
{
closeDb();
}
// 设置appExe安装目录
void cSqlLiteDatabase::setAppExePath(QString strPath)
{
m_strExePath = strPath;
createDir();
}
// 获取实例
cSqlLiteDatabase *cSqlLiteDatabase::getInstance()
{
static cSqlLiteDatabase obj;
return &obj;
}
// 创建配置文件夹
void cSqlLiteDatabase::createDir()
{
QDir dir;
m_strConfigPath = m_strExePath + QString("/Config");
if (!dir.exists(m_strConfigPath))
dir.mkpath(m_strConfigPath);
m_strDbDirPath = m_strConfigPath;
}
// 打开数据库
QSqlDatabase cSqlLiteDatabase::openDb(QString strDatabaseName, QString strDbDirPath)
{
if (!strDbDirPath.isEmpty())
m_strDbDirPath = strDbDirPath;
m_strDatabaseName = strDatabaseName;
QSqlDatabase db;
if (QSqlDatabase::contains(m_strDatabaseName))
db = QSqlDatabase::database(m_strDatabaseName);
else
{
QString strTempName = m_strDbDirPath + "/"+strDatabaseName;
db = QSqlDatabase::addDatabase("QSQLITE", m_strDatabaseName);
db.setDatabaseName(strTempName);
db.setPassword("8888");
db.setHostName("root");
db.setUserName("root");
}
if (!db.open())
qDebug() << db.lastError().text();
else
m_bConnected = true;
return db;
}
// 关闭数据库
bool cSqlLiteDatabase::closeDb()
{
QSqlDatabase::removeDatabase(m_strDatabaseName);
return true;
}
// 创建表
bool cSqlLiteDatabase::createTable(QString strTableName, QStringList strHeaderNameList)
{
bool bRet = true;
if (true)
{
if (strTableName.isEmpty() || strHeaderNameList.size() <= 0)
{
bRet = false;
return bRet;
}
auto findItem = m_strTableNameHeaderHash.find(strTableName);
if (findItem == m_strTableNameHeaderHash.end())
m_strTableNameHeaderHash.insert(strTableName, strHeaderNameList);
QString strCreateTable = QString(u8"CREATE TABLE %1(").arg(strTableName);
for (int i = 0; i < strHeaderNameList.size(); i++)
{
if (i < (strHeaderNameList.size() - 1))
strCreateTable = strCreateTable + strHeaderNameList[i] + QString(u8" VARCHAR(256)") + QString(",");
else
strCreateTable = strCreateTable + strHeaderNameList[i] + QString(u8" VARCHAR(256)") + QString(")");
}
bRet = excute(strCreateTable);
}
return bRet;
}
// 删除表
bool cSqlLiteDatabase::dropTable(QString strTableName)
{
if (strTableName.isEmpty())
return false;
QString strDrop = QString("DROP TABLE %1").arg(strTableName);
return excute(strDrop);
}
// 执行sql语句
bool cSqlLiteDatabase::excute(QString strSql)
{
static QMutex mutex;
mutex.lock();
bool bRet = true;
QSqlDatabase db = openDb(m_strDatabaseName);
QString strConnectionName = db.connectionName();
QSqlQuery query(db);
query.prepare(strSql);
bool success = query.exec(strSql);
if (!success)
{
qDebug() << "Error:" << query.lastError();
bRet = false;
}
closeDb();
mutex.unlock();
return bRet;
}
// 查找
QList<QStringList> cSqlLiteDatabase::seach(QString strTableName, QString strSql)
{
QList<QStringList> temp;
QSqlDatabase db = openDb(m_strDatabaseName);
QString strConnectionName = db.connectionName();
db.transaction(); // 开启事务查询
QSqlQuery query("", db);
query.exec(strSql);
db.commit(); // 提交事务
while (query.next())
{
QStringList keyValueHash;
int nCount = query.record().count();
for (size_t i = 0; i < nCount; i++)
keyValueHash << query.record().value(i).toString();
if (keyValueHash.size() > 0)
temp << keyValueHash;
}
closeDb();
return temp;
}
// 查找
QList< QHash<QString/*name*/, QString/*value*/> > cSqlLiteDatabase::select(QString strTableName, QString strName, QString strValue)
{
QList< QHash<QString, QString> > temp;
if (strTableName.isEmpty() || strTableName.isEmpty())
return temp;
QSqlDatabase db = openDb(m_strDatabaseName);
QString strConnectionName = db.connectionName();
QString strSelect("");
if (!strValue.isEmpty()&& !strName.isEmpty())
strSelect = QString("SELECT * FROM %1 WHERE %2 = '%3';").arg(strTableName).arg(strName).arg(strValue);
else
strSelect = QString("SELECT * FROM %1;").arg(strTableName);
db.transaction(); // 开启事务查询
QSqlQuery query("", db);
query.exec(strSelect);
db.commit(); // 提交事务
while (query.next())
{
QHash<QString, QString> keyValueHash;
int nCount = query.record().count();
for (size_t i = 0; i < nCount; i++)
keyValueHash.insert(query.record().fieldName(i), query.record().value(i).toString());
if (keyValueHash.size() > 0)
temp << keyValueHash;
}
closeDb();
return temp;
}
// 插入数据
bool cSqlLiteDatabase::insert(QString strTableName, QHash<QString/*name*/, QString/*value*/> dataHash)
{
bool bRet = false;
if (strTableName.isEmpty())
return bRet;
QStringList strHeaderList;
auto findItem = m_strTableNameHeaderHash.find(strTableName);
if (findItem == m_strTableNameHeaderHash.end())
return bRet;
else
strHeaderList = m_strTableNameHeaderHash[strTableName];
if (true)
{
QString strInsert = QString(u8"INSERT INTO %1 VALUES(").arg(strTableName);
for (size_t j = 0; j < strHeaderList.size(); j++)
{
QString strName = strHeaderList[j];
QString strValue = "";
auto findName = dataHash.find(strName);
if (findName != dataHash.end())
strValue = findName.value();
if (j < (strHeaderList.size() - 1))
strInsert = strInsert + QString(u8"'%1'").arg(strValue) + QString(",");
else
strInsert = strInsert + QString(u8"'%1'").arg(strValue) + QString(")");
}
bRet = excute(strInsert);
}
return bRet;
}
// 更新数据
bool cSqlLiteDatabase::update(QString strTableName, QString strWhereName, QString strWhereValue, QString strUpdateName, QString strUpdateValue)
{
bool bRet = false;
if (strTableName.isEmpty())
return bRet;
QStringList strHeaderList;
auto findItem = m_strTableNameHeaderHash.find(strTableName);
if (findItem == m_strTableNameHeaderHash.end())
return bRet;
if (true)
{
QString strUpdate = QString(u8"UPDATE %1 SET %2='%3' WHERE %4='%5';")
.arg(strTableName)
.arg(strUpdateName)
.arg(strUpdateValue)
.arg(strWhereName)
.arg(strWhereValue);
bRet = excute(strUpdate);
}
return bRet;
}
// 删除数据
bool cSqlLiteDatabase::remove(QString strTableName, QString strWhereName, QString strWhereValue)
{
bool bRet = false;
if (strTableName.isEmpty())
return bRet;
QStringList strHeaderList;
auto findItem = m_strTableNameHeaderHash.find(strTableName);
if (findItem == m_strTableNameHeaderHash.end())
return bRet;
if (true)
{
QString strUpdate = QString(u8"DELETE FROM %1 WHERE %2='%3';")
.arg(strTableName)
.arg(strWhereName)
.arg(strWhereValue);
bRet = excute(strUpdate);
}
return bRet;
}
// 模糊查询
QStringList cSqlLiteDatabase::fuzzySearch(QString strTableName, QString strName, QString strLike)
{
QStringList temp;
if (strTableName.isEmpty() || strTableName.isEmpty())
return temp;
QSqlDatabase db = openDb(m_strDatabaseName);
QString strConnectionName = db.connectionName();
QString strSelect("");
if (!strLike.isEmpty())
strSelect = QString("SELECT %1 FROM %2 WHERE %3 LIKE '%%4%' LIMIT 0,10;").arg(strName).arg(strTableName).arg(strName).arg(strLike);
else
return temp;
db.transaction(); // 开启事务查询
QSqlQuery query("", db);
query.exec(strSelect);
while (query.next())
{
QHash<QString, QString> keyValueHash;
for (size_t i = 0; i < query.record().count(); i++)
{
QString strName = query.record().fieldName(i);
QString strValue = query.record().value(i).toString();
if (!temp.contains(strValue) && (strLike != strValue))
temp << strValue;
}
}
db.commit(); // 提交事务
closeDb();
return temp;
}