关于Qt 读取ini文件一些相关问题和坑
关于Qt 读取ini文件一些相关问题和坑
1.应用场景
最近因工作需求需要对ini文件进行读写配置,读取ini文件内容生成控件信息,用户再通过控件相应的修改配置,重新写入ini文件中,实现一个小的配置工具。
2.编写前思路构想
使用QSetting 读取ini文件所有的group 实现为 qt组件 QGroupBox 在里面包含读取的所有 group内容的keys 为qt相应控件,而value为控件内容。
最后在通过map信息将生成的控件信息保存包含它们的section、key和value,最后再写入ini文件中。
3.遇到的问题
①.当ini文件中含有注释的时候,我们再次写入内容时新的数据会覆盖ini文件内容,所以注释会消失。
②.当ini文件中vlaue含有“ \ ”,只有单个反斜杠时 QSetting读取的值的" \ "会直接变为转义字符,并导致改字符消失。
4.解决和使用
解决问题①使用Windows自带API WritePrivateProfileString函数将需要的修改的内容进行写入其他内容不变。具体应用:
1.所用的WINAPI函数原型为:
BOOL WritePrivateProfileString(
LPCTSTR lpAppName,
LPCTSTR lpKeyName,
LPCTSTR lpString,
LPCTSTR lpFileName
);
其中各参数的意义:
LPCTSTR lpAppName 是INI文件中的一个字段名.
LPCTSTR lpKeyName 是lpAppName下的一个键名,通俗讲就是变量名.
LPCTSTR lpString 是键值,也就是变量的值,不过必须为LPCTSTR型或CString型的.
LPCTSTR lpFileName 是完整的INI文件名.
**CString strName,strTemp;
int nAge;
strName="李四";
nAge=12;
::WritePrivateProfileString("StudentInfo","Name",strName,"c:\\stud\\student.ini");**
最后内容为:
[StudentInfo]
Name = 李四
然后关于QSetting读取使用方法入如下:
//打开文件并指定为ini格式
**QSettings* configIni = new QSettings(file_path, QSettings::IniFormat);**
QStringList groupList = set.childGroups();//读取所有section
configIni .beginGroup(groupList.[0]); //读取开始节点信息
auto keys = configIni .allKeys(); //等到所有的key
configIni .value(keys.[0]).toString() //得到key对应的值
通过WritePrivateProfileString 将数据写入ini文件并保持原来各式和注释内容。
解决问题② :其实qt读取ini文件,解决读取路径反斜杠转义字符消失可以采用QTextStream 逐行读取,
如下:
QFile file("Server.ini");
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
return;
QTextStream in(&file);
QString qstrLine1 = in.readLine();
QString qstrLine2 = in.readLine();
这也是一个方式但是不好区分Group和key 用于我的需求。我采用的是同样是Windows API GetPrivateProfileString函数来读取字符,然后通过上面的QSetting读取遍历所有的Section和key来最后生成的map容器里面。如下:
std::map<std::string, std::map<std::string, std::string>> m_mIniReader;
QSettings set(path, QSettings::IniFormat);
QStringList groupList = set.childGroups();
TCHAR zsValue[MAX_INI_NUM + 1] = _T("");
for each (auto var in groupList) //通过windows的获取ini文件信息,保留里面的反斜杠字符串不为转义
{
set.beginGroup(var);
for each (auto val in set.allKeys())
{
GetPrivateProfileString(PX_QSLP(var), PX_QSLP(val), "DefaultName", zsValue, MAX_INI_NUM, PX_QSLP(path));
m_mIniReader[PX_QS2S(var)][PX_QS2S(val)] = (zsValue);
}
set.endGroup();//节点结束
}
这里注意的是 我用的自定义的宏来转字符格式: #define PX_QSLP(_S) (LPCSTR)_S.toLocal8Bit()
最后我再通过map里面的数据进行遍历的然后得到所有控件信息。
PS:所以当读取ini文件时QSetting还是存在一些问题。具体QSetting其他用法以后再记录!