QT_INI文件操作

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)
    • 五、补充:日常开发常用技巧
      • [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 文件时的中文编码问题)
    • 六、注意事项与建议

一、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 系统中,NativeFormatIniFormat 同属文本文件,区别仅在于默认扩展名不同:NativeFormat.confIniFormat.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 的键名有两种等价写法:

  1. 绝对路径写法 (以 / 或分组路径开头):
cpp 复制代码
settings.setValue("/database/ip", "192.168.1.189");

生成的结构为:

ini 复制代码
[database]
ip=192.168.1.189
  1. 分组 + 相对键名写法 (配合 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 文件。


六、注意事项与建议

  1. 指针管理 :示例中使用了 new 创建 QSettings,务必在合适位置 delete,避免内存泄漏(更推荐直接使用栈对象 QSettings setting(...),无需手动释放)。
  2. 键名一致性:写入与读取的键名(含分组路径)必须完全一致,否则读取结果为空。
  3. 文件编码:保持 UTF-8 编码,避免中文乱码。
  4. 线程安全:QSettings 并非线程安全,多线程访问时需加锁或各自使用独立实例。
  5. 密码安全:数据库密码以明文存储于 INI 文件中,正式发布时应考虑加密后再存。
  6. 同步写入 :若希望修改立即落盘,可调用 sync()(默认在析构时也会自动同步)。
相关推荐
FfHUCisI1 小时前
Golang RESTful API 设计原则
开发语言·golang·restful
breeze jiang1 小时前
ESLint flat config 配置实战:五大字段、规则严重级别与 --fix 能力边界详解
开发语言·前端·javascript
weixin_307779132 小时前
PHP 大文件上传:内存占用、超时与最佳实践
linux·服务器·开发语言·nginx·php
m0_527034332 小时前
异步任务审核系统设计:消息队列、超时重试与失败补偿
java·大数据·开发语言
一朵好运莲2 小时前
智能体使用 Chrome DevTools MCP 调试浏览器
开发语言·javascript·react.js
秋田君2 小时前
QT_JSON文件操作
开发语言·qt·json
老赵的博客2 小时前
可维护性 可扩展性 可复用性
开发语言·c++
sibylyue2 小时前
工作流表单和流程设计前端
开发语言·javascript·开源
一个游离的指针2 小时前
JS中的对象的相关概念
开发语言·javascript·原型模式
jaysee-sjc3 小时前
【JavaWeb】Tlias智能学习辅助系统|后端Web实战(登录认证)
java·开发语言·前端·学习·mybatis