QT_INI 文件操作
文章目录
- [QT_INI 文件操作](#QT_INI 文件操作)
-
- [一、INI 文件概述](#一、INI 文件概述)
-
- [1.1 一个完整的 INI 文件示例](#1.1 一个完整的 INI 文件示例)
- [1.2 INI 文件的使用场景](#1.2 INI 文件的使用场景)
- [二、QSettings 简介](#二、QSettings 简介)
-
- [2.1 存储格式(Format)](#2.1 存储格式(Format))
- [2.2 常用 API](#2.2 常用 API)
- [2.3 构造 QSettings 的几种方式](#2.3 构造 QSettings 的几种方式)
- 三、键名的两种写法
- [四、QT 读取 .ini 配置文件案例](#四、QT 读取 .ini 配置文件案例)
-
- [4.1 头文件 `wrinifile.h`](#4.1 头文件
wrinifile.h) - [4.2 源文件 `wrinifile.cpp`](#4.2 源文件
wrinifile.cpp) - [4.3 源文件 `main.cpp`](#4.3 源文件
main.cpp)
- [4.1 头文件 `wrinifile.h`](#4.1 头文件
- 五、补充:日常开发常用技巧
-
- [5.1 使用 `contains()` 判断键是否存在](#5.1 使用
contains()判断键是否存在) - [5.2 在 `value()` 中直接指定默认值](#5.2 在
value()中直接指定默认值) - [5.3 使用数组保存列表数据(`beginWriteArray` / `beginReadArray`)](#5.3 使用数组保存列表数据(
beginWriteArray/beginReadArray)) - [5.4 使用 `group()` 简化键的管理](#5.4 使用
group()简化键的管理) - [5.5 修改 / 覆盖已有配置项](#5.5 修改 / 覆盖已有配置项)
- [5.6 删除指定的配置项](#5.6 删除指定的配置项)
- [5.7 判断并修改端口类型(字符串 → 整数)](#5.7 判断并修改端口类型(字符串 → 整数))
- [5.8 关于配置文件路径的注意事项](#5.8 关于配置文件路径的注意事项)
- [5.9 使用 `status()` 检查操作是否成功](#5.9 使用
status()检查操作是否成功) - [5.10 读取 INI 文件时的中文编码问题](#5.10 读取 INI 文件时的中文编码问题)
- [5.1 使用 `contains()` 判断键是否存在](#5.1 使用
- 六、注意事项与建议
一、INI 文件概述
.ini 文件是 Initialization file(初始化文件)的缩写,是 Windows 系统配置文件所采用的经典存储格式。
文件扩展名 :配置文件名.ini。例如项目中共用的配置文件 数据库配置.ini(database.ini)。
INI 文件由 节(section) 、键(key) 、值(value) 三部分组成:
- 节:
[section],用方括号包裹,用于对配置项分组; - 参数(键值对):
name = value,键名 = 值。
注释 :以分号 ; 开头,从 ; 开始到该行结尾均为注释内容。
例如:
ini
[sectionname]
Keyname = value
1.1 一个完整的 INI 文件示例
ini
; 这是注释,不会被解析
[database]
ip = 192.168.1.189
port = 8080
user = root
pwd = root@123
[notice]
version = 5.6
datetime = 2026.08.13 22:37
1.2 INI 文件的使用场景
- 数据库连接信息(地址、端口、用户名、密码);
- 软件运行时参数(窗口大小、主题、语言);
- 应用版本号、更新日期等元信息;
- 用户个性化偏好设置。
优点:简单、直观、纯文本、跨平台、易于手动编辑和版本管理。
二、QSettings 简介
在整个操作过程中,Qt 使用 QSettings 类对 INI 文件进行读写。QSettings 提供了跨平台的持久化配置存储能力。
2.1 存储格式(Format)
QSettings 支持多种存储格式:
| 格式枚举 | 说明 |
|---|---|
QSettings::NativeFormat |
本机默认格式(Windows 为注册表,macOS 为 plist) |
QSettings::IniFormat |
INI 文本文件格式 |
QSettings::InvalidFormat |
无效格式(用于错误处理) |
在 Unix 系统中,
NativeFormat与IniFormat同属文本文件,区别仅在于默认扩展名不同:NativeFormat为.conf,IniFormat为.ini。
2.2 常用 API
| API | 说明 |
|---|---|
QSettings::beginGroup() |
进入指定分组(后续操作均在该分组/节下) |
QSettings::endGroup() |
退出当前分组,返回上层 |
QSettings::setValue() |
写入一个键值对 |
QSettings::value() |
读取一个键的值(可指定默认值) |
QSettings::group() |
返回当前所在的分组名 |
QSettings::allKeys() |
返回所有键名(含分组前缀,返回 QStringList) |
QSettings::contains() |
判断某个键是否存在 |
QSettings::remove() |
删除指定键 |
QSettings::clear() |
清空当前分组下的所有键 |
QSettings::sync() |
将内存中的修改立即同步回磁盘文件 |
QSettings::status() |
返回最近一次操作的错误状态 |
QSettings::beginWriteArray() |
开始写入数组(用于保存列表数据) |
QSettings::beginReadArray() |
开始读取数组 |
QSettings::endArray() |
结束数组读写 |
2.3 构造 QSettings 的几种方式
cpp
// 方式1:指定文件名 + 格式(最常用,本例采用此方式)
QSettings settings("MySQLFiles.ini", QSettings::IniFormat);
// 方式2:指定带路径的文件名
QSettings settings("./config/MySQLFiles.ini", QSettings::IniFormat);
// 方式3:使用组织名 + 应用名(按平台默认位置存储)
QSettings settings("MyCompany", "MyApp");
三、键名的两种写法
QSettings 的键名有两种等价写法:
- 绝对路径写法 (以
/或分组路径开头):
cpp
settings.setValue("/database/ip", "192.168.1.189");
生成的结构为:
ini
[database]
ip=192.168.1.189
- 分组 + 相对键名写法 (配合
beginGroup/endGroup):
cpp
settings.beginGroup("database");
settings.setValue("ip", "192.168.1.189");
settings.endGroup();
两种写法生成的结果完全一致,分组写法在键较多时更清晰,且可避免手写路径出错。
四、QT 读取 .ini 配置文件案例
4.1 头文件 wrinifile.h
cpp
#ifndef WRINIFILE_H
#define WRINIFILE_H
void WriteIniFiles(); // 写配置文件
void ReadIniFiles(); // 读配置文件
void ReadIniFilesIsKey(); // 遍历读取所有配置项
#endif // WRINIFILE_H
4.2 源文件 wrinifile.cpp
cpp
#include "wrinifile.h"
#include "QSettings"
#include "QtDebug"
void WriteIniFiles(){
// 直接使用 QSettings 类读写 INI 文件
QSettings *ConfigWriteIniFiles = new QSettings("MySQLFiles.ini", QSettings::IniFormat);
// 向 INI 文件当中写入数据信息(第一节的第一个参数)
ConfigWriteIniFiles->setValue("/database/ip", "192.168.1.189");
ConfigWriteIniFiles->setValue("/database/port", "8080");
ConfigWriteIniFiles->setValue("/database/user", "root");
ConfigWriteIniFiles->setValue("/database/pwd", "root@123");
ConfigWriteIniFiles->setValue("/notice/version", "5.6");
ConfigWriteIniFiles->setValue("/notice/datetime", "2026.08.13 22:37");
// 向 INI 文件写入完成之后,删除指针
delete ConfigWriteIniFiles;
}
// 读取配置文件
void ReadIniFiles(){
QSettings *ConfigReadIniFiles = new QSettings("MySQLFiles.ini", QSettings::IniFormat);
QString strip = ConfigReadIniFiles->value("/database/ip").toString();
QString strport = ConfigReadIniFiles->value("/database/port").toString();
QString struser = ConfigReadIniFiles->value("/database/user").toString();
QString strpwd = ConfigReadIniFiles->value("/database/pwd").toString();
QString strversion = ConfigReadIniFiles->value("/notice/version").toString();
QString strdatetime = ConfigReadIniFiles->value("/notice/datetime").toString();
// 输出读取配置文件的参数信息
qDebug() << "读取 ini 配置文件参数选项如下:";
qDebug() << "数据库地址:" << strip.toUtf8().data();
qDebug() << "数据库端口:" << strport.toUtf8().data();
qDebug() << "数据库用户:" << struser.toUtf8().data();
qDebug() << "数据库密码:" << strpwd.toUtf8().data();
qDebug() << "数据库版本:" << strversion.toUtf8().data();
qDebug() << "数据库日期:" << strdatetime.toUtf8().data();
// 读取配置文件完成之后,删除指针
delete ConfigReadIniFiles;
}
void ReadIniFilesIsKey(){
QSettings setting("./MySQLFiles.ini", QSettings::IniFormat);
foreach(QString key, setting.allKeys()){
qDebug() << key << "," << setting.value(key).toString();
}
}
4.3 源文件 main.cpp
cpp
#include <QCoreApplication>
#include <wrinifile.h>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
// 调用写入配置文件
WriteIniFiles();
// 调用读取配置文件
ReadIniFiles();
qDebug() << "--------------foreach 读取--------------------";
// foreach 读取
ReadIniFilesIsKey();
return a.exec();
}

五、补充:日常开发常用技巧
5.1 使用 contains() 判断键是否存在
读取前先判断键是否存在,避免取到空值导致逻辑错误:
cpp
QSettings setting("MySQLFiles.ini", QSettings::IniFormat);
if (setting.contains("/database/ip")) {
QString ip = setting.value("/database/ip").toString();
qDebug() << "ip:" << ip;
} else {
qDebug() << "未找到 database/ip 配置项,使用默认值";
QString ip = "127.0.0.1"; // 默认值
}
5.2 在 value() 中直接指定默认值
value() 支持第二个参数作为默认值,键不存在时返回该默认值:
cpp
QSettings setting("MySQLFiles.ini", QSettings::IniFormat);
QString ip = setting.value("/database/ip", "127.0.0.1").toString();
int port = setting.value("/database/port", 3306).toInt();
qDebug() << "ip:" << ip << "port:" << port;
5.3 使用数组保存列表数据(beginWriteArray / beginReadArray)
适用于保存多条同结构数据,例如多台服务器的 IP 列表:
cpp
// 写入数组
QSettings setting("servers.ini", QSettings::IniFormat);
setting.beginWriteArray("servers");
setting.setArrayIndex(0);
setting.setValue("ip", "192.168.1.100");
setting.setValue("name", "主服务器");
setting.setArrayIndex(1);
setting.setValue("ip", "192.168.1.101");
setting.setValue("name", "备份服务器");
setting.endArray();
// 读取数组
int size = setting.beginReadArray("servers");
for (int i = 0; i < size; ++i) {
setting.setArrayIndex(i);
QString ip = setting.value("ip").toString();
QString name = setting.value("name").toString();
qDebug() << "第" << i << "台:" << name << ip;
}
setting.endArray();
更推荐使用 C++11 的
for (const QString &key : setting.allKeys())替代 Qt 的foreach宏(Qt 官方已逐步弃用foreach)。
5.4 使用 group() 简化键的管理
cpp
QSettings setting("MySQLFiles.ini", QSettings::IniFormat);
setting.beginGroup("database");
setting.setValue("ip", "192.168.1.189");
setting.setValue("port", "8080");
setting.endGroup();
setting.beginGroup("notice");
setting.setValue("version", "5.6");
setting.endGroup();
5.5 修改 / 覆盖已有配置项
setValue() 对已存在的键会直接覆盖其值,无需单独删除:
cpp
QSettings setting("MySQLFiles.ini", QSettings::IniFormat);
setting.setValue("/database/port", "9090"); // 端口从 8080 改为 9090
5.6 删除指定的配置项
cpp
QSettings setting("MySQLFiles.ini", QSettings::IniFormat);
// 删除单个键
setting.remove("/notice/datetime");
// 删除整个分组下的所有键
setting.beginGroup("notice");
setting.remove(""); // 空字符串表示删除当前分组全部键
setting.endGroup();
5.7 判断并修改端口类型(字符串 → 整数)
端口通常应为整数类型,读取时建议转换为 int:
cpp
QSettings setting("MySQLFiles.ini", QSettings::IniFormat);
int port = setting.value("/database/port", 3306).toInt();
if (port <= 0 || port > 65535) {
qDebug() << "端口号不合法:" << port;
}
5.8 关于配置文件路径的注意事项
cpp
// 相对路径:相对于程序当前工作目录(运行时可变的当前目录)
QSettings setting("./MySQLFiles.ini", QSettings::IniFormat);
// 明确指定应用目录下的 config 子目录
QCoreApplication app(argc, argv);
QSettings setting(app.applicationDirPath() + "/config/MySQLFiles.ini",
QSettings::IniFormat);
实际项目中,建议把配置文件放到程序所在目录下的
config/子目录,避免使用容易变化的相对当前目录。
5.9 使用 status() 检查操作是否成功
cpp
QSettings setting("MySQLFiles.ini", QSettings::IniFormat);
if (setting.status() != QSettings::NoError) {
qDebug() << "读写 INI 文件时发生错误,状态码:" << setting.status();
}
5.10 读取 INI 文件时的中文编码问题
当 INI 文件包含中文时,需注意编码。QSettings 写 INI 文件默认使用 UTF-8,若用其他编辑器(如 Windows 记事本)保存为 ANSI/GBK 编码,读取时可能出现乱码。建议统一使用 UTF-8 编码保存 INI 文件。
六、注意事项与建议
- 指针管理 :示例中使用了
new创建 QSettings,务必在合适位置delete,避免内存泄漏(更推荐直接使用栈对象QSettings setting(...),无需手动释放)。 - 键名一致性:写入与读取的键名(含分组路径)必须完全一致,否则读取结果为空。
- 文件编码:保持 UTF-8 编码,避免中文乱码。
- 线程安全:QSettings 并非线程安全,多线程访问时需加锁或各自使用独立实例。
- 密码安全:数据库密码以明文存储于 INI 文件中,正式发布时应考虑加密后再存。
- 同步写入 :若希望修改立即落盘,可调用
sync()(默认在析构时也会自动同步)。