软件开发时候,往往需要利用QSettings写入ini配置文件
多次调用QSettings的读写加大代码量,同时,修改时也会加大难度。
为此封装一个ConFRouter类,利用QSettings统一管理配置文件里的内容。
1. ConFRouter.h
class DLL_API ConFRouter
{
public:
static ConFRouter* create_confrouter(const QString& path = QString(""));
void save_file();
void read_file();
QString& operator[](const QString& key);
private:
ConFRouter(const QString& path);
QString _root;
QHash _find;
QString _case_path;
QString _screen_shot_path;
QString _video_path;
QString _display_value;
std::vector _groups = {
"CaseGroup",
"PathGroup"
};
std::vector<vector > _keynames = {
{ "case_path" },
{ "video_path", "screen_shot_path", "display_value" }
};
};
2. ConFRouter.cpp
ConFRouter* ConFRouter::create_confrouter(const QString& path)
{
static ConFRouter* con_pointer = nullptr;
if (con_pointer == nullptr)
{
assert(path.size() != 0);
con_pointer = new ConFRouter(path);
}
return con_pointer;
}
ConFRouter::ConFRouter(const QString& path)
{
auto make_hashs = [](const std::vector<vector >& keynames,
const std::vector<vector >& pointers) {
QHash hashs;
assert(keynames.size() == pointers.size());
for (size_t i = 0; i < keynames.size(); i++)
{
assert(keynames[i].size() == pointers[i].size());
for (size_t j = 0; j < keynames[i].size(); j++)
hashs.insert(keynames[i][j], pointers[i][j]);
}
return hashs;
};
auto set_defult = [=](const std::vector<vector >& pointers,
const std::vector<vector > defaults) {
assert(defaults.size() == pointers.size());
for (size_t i = 0; i < pointers.size(); i++)
{
assert(defaults[i].size() == pointers[i].size());
for (size_t j = 0; j < pointers[i].size(); j++)
*(pointers[i][j]) = defaults[i][j];
}
};
std::vector<vector > defaults = {
{ path + "/vinci_case" },
{ path + "/avi", path + "/screenshot", "0.03" }
};
std::vector<vector > pointers = {
{ &_case_path },
{ &_video_path, &_screen_shot_path, &_display_value }
};
_root = path;
_find = make_hashs(_keynames, pointers);
set_defult(pointers, defaults);
this->read_file();
}
void ConFRouter::save_file()
{
std::shared_ptr con = std::shared_ptr(
new QSettings(_root + "/settings.ini", QSettings::IniFormat),
[](QSettings *setting) { delete setting; }
);
for (size_t i = 0; i < _groups.size(); i++)
{
con->beginGroup(_groups[i]);
for (size_t j = 0; j < _keynames[i].size(); j++)
con->setValue(_keynames[i][j], (*this)[_keynames[i][j]]);
con->endGroup();
}
con->sync();
}
void ConFRouter::read_file()
{
std::shared_ptr con = std::shared_ptr(
new QSettings(_root + "/settings.ini", QSettings::IniFormat),
[](QSettings *setting) { delete setting; }
);
for (size_t i = 0; i < _groups.size(); i++)
{
con->beginGroup(_groups[i]);
for (size_t j = 0; j < _keynames[i].size(); j++)
{
QString value = con->value(_keynames[i][j]).toString();
if (value.size() != 0)
(*this)[_keynames[i][j]] = value;
}
con->endGroup();
}
}
QString & ConFRouter::operator[](const QString & key)
{
auto pointer = this->_find.find(key);
assert(pointer != this->_find.end());
return *(pointer.value());
}
1.mainWnd中声明Path
在创建mainWnd时候,在对应得appPath下创建setting.ini
#include "ConFRouter.h"
...
ConFRouter::create_confrouter(QApplication::applicationDirPath());
2.读取setting.ini
读取的信息为QString类型,需要我们自己对类型转换。
void CSettingDlg::read_iniFile()
{
auto con = ConFRouter::create_confrouter();
QString screenShotPath = (*con)["screen_shot_path"];
QString videoPath = (*con)["video_path"];
QString displayValue = (*con)["display_value"];
if ((checkFloderPath(screenShotPath) == FloderPath::INVALID)) {
(*con)["screen_shot_path"] = this->_appPath;
screenShotPath = this->_appPath;
}
if ((checkFloderPath(videoPath) == FloderPath::INVALID)) {
(*con)["video_path"] = this->_appPath;
videoPath = this->_appPath;
}
bool ok;
displayValue.toDouble(&ok);
if (ok == false) {
(*con)["display_value"] = 0.3;
displayValue = 0.3;
}
con->save_file();
this->_screen_shot_edit->setText(screenShotPath);
this->_video_edit->setText(videoPath);
this->_display_box->setValue(displayValue.toDouble());
}
3.修改setting.ini的内容
void CSettingDlg::write_iniFile()
{
auto con = ConFRouter::create_confrouter();
QString screenShotPath = this->_screen_shot_edit->text();
QString videoPath = this->_video_edit->text();
double displayValue = this->_display_box->value();
(*con)["screen_shot_path"] = screenShotPath;
(*con)["video_path"] = videoPath;
(*con)["display_value"] = QString("%1").arg(displayValue);
con->save_file();
}
读取到的路径,需要写入一个func判断路径是否合理。
int CSettingDlg::checkFloderPath(const QString path)
{
if (0 == path.size())
return FloderPath::INVALID;
QStringList allDirs;
if (path.contains("/"))
allDirs = path.split("/", QString::SkipEmptyParts);
else
allDirs = path.split("\\", QString::SkipEmptyParts);
QString dirPath = allDirs.at(0);
QFileInfo rootPath(dirPath + "/");
if (false == rootPath.isRoot())
return FloderPath::INVALID;
QDir dir;
for (size_t i = 1; i < allDirs.size(); i++)
{
dirPath = dirPath + "/" + allDirs.at(i);
if (false == dir.exists(dirPath)) {
if (false == dir.mkdir(dirPath))
return FloderPath::INVALID;
}
}
return FloderPath::VALID;
}