总结:Qt读写ini配置文件(QSettings)

news/2024/9/30 0:19:06/

一、ini文件介绍

.ini 文件是Initialization File的缩写,即初始化文件。

INI文件被用来对操作系统或特定程序初始化或进行参数设置,以实现不同用户的要求。

一般不用直接编辑这些.ini文件,应用程序的图形界面即可操作以实现相同的功能。

在Qt中可以使用QSetting类来实现ini文件的读取和写入。

二、ini文件格式

ini文件主要有节(section)、键(key)、键值(value)部分组成。

节 (section) 用方括号括起来,单独占一行,例如:

[section]

键(key)又名属性(property),单独占一行用等号连接键名和键值,例如:

name=value

例子

[Section1 Name]   
KeyName1=value1   
KeyName2=value2   
...   
[Section2 Name]   
KeyName21=value21   
KeyName22=value22 

其中:[Section1 Name]用来表示一个段落。

因为INI文件可能是项目中共用的,所以使用[Section Name]段名来区分不同用途的参数区。

注意:使用分号表示(;)。在分号后面的文字,直到该行结尾都全部为注解。

三、QSettings

Qt通过QSettings类读写ini文件。

QSettings的存储设置,每个设置都由一个QString和一个QVariant组成,

QString指定设置的名称(键),QVariant存储与该键关联的数据。 

头文件:QSetting.h
QSetting读写ini文件的步骤为:* 通过路径名称打开文件并设定为ini文件格式* 读/写数据* 关闭文件,删除句柄

QSettings::Format有两种:

QSettings::NativeFormat在windows平台可以读写windows注册表;

QSettings::IniFormat可以读写ini格式的配置文件。

3.1 写ini文件

// 根据ini文件路径新建QSettings类
QSettings  m_IniFile = new QSettings("ini文件的路径", QSettings::IniFormat);//通过setValue函数将键值对放在相对于的节下面
m_IniFile->setValue( "节名" + "/" + "键名",  "键对应的值");
delete m_IniFile;分组写入
//根据ini文件路径新建QSettings类
QSettings  m_IniFile = new QSettings("ini文件的路径", QSettings::IniFormat);
m_IniFile ->beginGroup("节名");     // 设置当前节名,代表以下的操作都是在这个节中
m_IniFile->setValue( "键名",  "键对应的值"); // 因为上面设置了节了,这里不在需要把节名写上去
m_IniFile.endGroup();                   // 结束当前节的操作
delete m_IniFile;

//Qt中使用QSettings类读写ini文件
//QSettings构造函数的第一个参数是ini文件的路径,第二个参数表示针对ini文件,第三个参数可以缺省
QSettings *configIniWrite = new QSettings("config.ini", QSettings::IniFormat);
//向ini文件中写入内容,setValue函数的两个参数是键值对
//向ini文件的第一个节写入内容,ip节下的第一个参数
configIniWrite->setValue("/con/ip", "192.168.0.1");
//向ini文件的第一个节写入内容,ip节下的第二个参数
configIniWrite->setValue("/con/name", "aa");
//向ini文件的第二个节写入内容,port节下的第一个参数
configIniWrite->setValue("port/open", "2222");
configIniWrite->setValue("port/ports", "2222,111,33,444");
//写入完成后删除指针
delete configIniWrite;生成文件 config.ini
[con]
ip=192.168.0.1
name=aa[port]
open=2222
ports="2222,111,33,444"

3.2 读ini文件

//通过Value函数将节下相对应的键值读取出来
QString value = m_IniFile->Value( "节名" + "/" + "键名").toString;
//打开文件并指定为ini格式
QSettings* configIni = new QSettings(file_path, QSettings::IniFormat);
QString qTemp = "";
//读指定节点的指定数据,其中“Log”为节点,save_days为具体数据项
logDays = configIni->value("Log/save_days").toInt();
qTemp = configIni->value("Log/print_debug").toString();
printDbgLog = qTemp.compare("true", Qt::CaseInsensitive) == 0 ? true : false;
//删除指针,此处未关联父对象,必须手动删除,否则有内存泄露风险
delete configIni;分组读取
settings.beginGroup("Setting");
QString strName = settings.value("Name").toString();
int nVersion = settings.value("Version").toInt();
settings.endGroup();
//Name:Qt Creator  Version:5settings.beginGroup("User");
QString strUserName = settings.value("UserName").toString();
QString strPassword = settings.value("Password").toString();
settings.endGroup();
//UserName:WangL  Password:123456

[conn]
name=aaa
ip="192.168.1.10"
auto_con=1
speed=50
joints=0.000,-13.959,2.2,83.3,0.000,18.000,-30.000
tcp_offset= 133.4,0.0,0.0,0.0,0.0,-10.0读配置文件
QSettings setting("config.ini",QSettings::IniFormat);
setting.setIniCodec("utf-8");// 解决乱码
QString name =setting.value("conn/name").toString();
int speed =setting.value("conn/speed").toInt();qDebug() << name;
qDebug() << speed;输出:
"aaa"
50

四、问题总结

4.1 QSettings写入数据丢失

在实际使用中,QSettings的写操作在某些情况下会丢失数据。

尤其在嵌入式Liunx环境中,通过断电方式关机,更容易丢失数据。

原因分析:

1,Qt的保存机制是先写到一个临时文件中,然后定时去同步到磁盘,所以不能实时生效。

2,setValue函数设置指定KEY的值,若该值已存在则替换先前的值,但不立即回写文件。

3,QSettings类的sync方法并不能立刻同步到磁盘上,需要使用系统sync或syncFlushFileBuffers进行同步。

解决措施:

1,在写完后调用QSettings的函数settings.sync();

2,调用Linux系统的shell命令system("sync");

#include <QtCore/QtCore>
#include <QSettings>
#include <QFile>
#include <QDebug>
#include <QTextCodec> void ConfigSetting(void)
{//文件路径+文件名QString fileName = QCoreApplication::applicationDirPath() + "/Config.ini";//创建配置目标,输入文件路径,文件格式QSettings *setting = new QSettings(fileName , QSettings::IniFormat);//设置文件编码,配置文件中使用中文时,这是必须的,否则乱码setting->setIniCodec(QTextCodec::codecForName("UTF-8"));// 判断文件是否存在if(QFile::exists(fileName)){// 文件存在,读出配置项// 这里的setting->value的第二参数,是配置项缺省值,即当读取的配置项不存在时,读取该值// User是配置组,name和age是配置项QString name = setting->value("User/name", "张三").toString();int age = setting->value("User/age", 30).toInt();}else {// 文件不存在,写入配置项,生成配置文件setting->setValue("User/name", "张三");setting->setValue("User/age", 30);// setValue只是把配置项写入了缓冲区,若要写入文件,还需执行同步// 不同步,无法写入文件,无法生成文件setting->sync();system("sync");//将内核缓冲写入文件(磁盘)}delete setting;
}

4.2 QSettings读取ini配置文件乱码

QSetting中的key值与项目标题如果用中文的话,打开会是乱码。

QSetting中变量值中如果包含分号,则值字符串需要用双引号(" ")来引用,

否则取值时候,只会取值到该变量第一个分号之前的内容。

4.3 QSettings保存float 类型数据时乱码

使用QSettings 将 float 类型的数据写入到ini时

float dx = 1.0;

  sParamSetting->setValue("SectionData/d_correct",dx);

ini文件中内容如下:

d_correct=@Variant(\0\0\0\x87\xbeH\xb4\x39)

这是因为 QSettings在写float类型时有点问题,可以将float强制转化为double就可以了。

也可以将变量设置为double dx = 1.0;

sParamSetting->setValue("SectionData/d_correct", (double)(sCorrectParam.lcz_correct));

资料来源

https://www.cnblogs.com/qianxiaoPro/p/15623881.html

https://www.cnblogs.com/xiangtingshen/p/11145974.html

https://blog.csdn.net/yinyuchen1/article/details/75093895

https://www.cnblogs.com/mzy-google/p/5162107.html

https://blog.csdn.net/qq_33485434/article/details/80483883

https://blog.csdn.net/weixin_40583088/article/details/104660595


http://www.ppmy.cn/news/1431165.html

相关文章

【PCL】教程global_hypothesis_verification 通过验证模型假设来实现 3D 对象识别与位姿估计...

测试程序1 milk.pcd milk_cartoon_all_small_clorox.pcd 终端输出1&#xff1a; Model total points: 12575; Selected Keypoints: 193 Scene total points: 307200; Selected Keypoints: 7739 [pcl::SHOTEstimation::computeFeature] The local reference frame is not valid!…

vue3组件封装系列-表单请求

我们在开发一些后台管理系统时&#xff0c;总是会写很多的列表查询页面&#xff0c;如果不封装组件&#xff0c;就会无限的复制粘贴&#xff0c;而且页面很冗余&#xff0c;正常情况下&#xff0c;我们都是要把组件进行二次封装&#xff0c;来达到我们想要效果。这里我分享一下…

【链表】Leetcode 两数相加

题目讲解 2. 两数相加 算法讲解 我们这里设置一个头结点&#xff0c;然后遍历两个链表&#xff0c;使用一个flag记录相加的结果和进位&#xff0c;如果两个链表没有走到最后或者进位不等于0&#xff0c;我们就继续遍历处理进位&#xff1b;如果当前的链表都遍历完成了&#x…

asio之地址

address address作为address_v4和address_v6的包装器 #mermaid-svg-XZWMK64K5NucyHdI {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-XZWMK64K5NucyHdI .error-icon{fill:#552222;}#mermaid-svg-XZWMK64K5NucyHdI …

《前端面试题》- TypeScript - TypeScript的优/缺点

问题 简述TypeScript的优/缺点 答案 优点 增强了代码的可读性和可维护性包容性&#xff0c;js可以直接改成ts&#xff0c;ts编译报错也可以生成js文件&#xff0c;兼容第三方库&#xff0c;即使不是ts编写的社区活跃&#xff0c;完全支持es6 缺点 增加学习成本增加开发成…

Tesseract OCR 的使用

目录 前言一、简介二、下载与安装2.1 下载2.2 安装2.3 配置环境变量 三、基本使用四、Java 整合4.1 导入依赖4.2 添加语言库4.3 代码示例 五、训练字库5.1 为什么要训练字库5.2 jTessBoxEditor 前言 如果想要通过代码的方式去识别图片中的文字&#xff0c;通常有以下几种方法&…

OpenCV-复数矩阵点乘ComplexMatrixDotMultiplication

作者&#xff1a;翟天保Steven 版权声明&#xff1a;著作权归作者所有&#xff0c;商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处 需求说明 一般用到FFT&#xff0c;就涉及到复数的计算&#xff0c;为了便于调用&#xff0c;我自行封装了一个简单的复数矩阵点乘…

JVM中的堆和栈

在Java虚拟机(JVM)中&#xff0c;堆(heap)和栈(stack)是两个重要的内存区域&#xff0c;分别用来存储不同类型的数据。 堆是用来存储对象的内存区域&#xff0c;所有的Java对象都在堆中分配内存。堆是一个动态的内存区域&#xff0c;它的大小可以在程序运行时动态调整。Java垃…