QT -= gui CONFIG += c++11 console CONFIG -= app_bundle SOURCES += main.cpp#include <QCoreApplication> #include <QSettings> #include <QDebug> int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); // 使用源码目录的绝对路径 QString configPath = "d:/QtCode/IniTest/config.ini"; qDebug() << "configPath:" << configPath; QSettings settings(configPath, QSettings::IniFormat); // 调试:检查文件是否找到 if (settings.allKeys().isEmpty()) { qDebug() << "警告: 未读取到任何配置项,请检查文件路径"; } qDebug() << "===== 方式一: allKeys 遍历所有键值 ====="; const QStringList allKeys = settings.allKeys(); for (const QString &key : allKeys) { qDebug().noquote() << key << "=" << settings.value(key).toString(); } qDebug() << "\n===== 方式二: 按 section/key 读取 ====="; qDebug() << "user/name =" << settings.value("user/name").toString(); qDebug() << "user/age =" << settings.value("user/age").toInt(); qDebug() << "server/host =" << settings.value("server/host").toString(); qDebug() << "server/port =" << settings.value("server/port").toInt(); qDebug() << "server/notExist (默认值) =" << settings.value("server/notExist", 12345).toInt(); qDebug() << "logging/enabled =" << settings.value("logging/enabled").toBool(); qDebug() << "\n===== 方式三: beginGroup 分组读取 ====="; settings.beginGroup("server"); qDebug() << "host =" << settings.value("host").toString(); qDebug() << "port =" << settings.value("port").toInt(); qDebug() << "timeout =" << settings.value("timeout").toInt(); settings.endGroup(); qDebug() << "\n===== 方式四: 遍历所有分组 ====="; const QStringList groups = settings.childGroups(); for (const QString &group : groups) { qDebug() << "section:" << group; } return 0; }config.ini
[user] name=张三 age=25 email=zhangsan@example.com [server] host=192.168.1.100 port=8080 timeout=3000 [logging] enabled=true level=debug读到了,但是中文部分是乱码。
修改程序:
QSettings settings(configPath, QSettings::IniFormat); settings.setIniCodec("UTF-8");可以了!
继续修改:
使用相对路径:
QString configPath = QCoreApplication::applicationDirPath() + "/config.ini"; qDebug() << "configPath:" << configPath;构造函数:QSettings("config.ini", QSettings::IniFormat)指定文件路径和格式。不指定格式时默认用注册表(Windows)或 plist(macOS),读 INI 必须显式指定QSettings::IniFormat。
键名规则:INI 中的[section]变成section/key形式的扁平键,如[user]下的name用"user/name"访问。
返回 QVariant:value()返回QVariant,需要.toString()、.toInt()、.toBool()等转换。QSettings 会自动把true/false识别为布尔、纯数字识别为数值。
提问,如果组名为General,这时候我就读不到信息了,为什么?
[General] localAddress=192.168.68.1 peerAddress=192.168.68.100 peerPort=1234 localPort=1235qDebug() << "localAddress" << settings.value("General/localAddress").toString();打印:
localAddress ""
这是 QSettings 的一个特殊行为:[General]是 QSettings 的保留组名。
原因
QSettings 把 INI 文件中的[General]组视为顶层(无组前缀)。也就是说:
[General] name=张三 age=25在 QSettings 看来,这两个键没有组前缀,读取方式是:
settings.value("name"); // 正确 settings.value("General/name"); // 错误,读不到!测试:
const QStringList allKeys = settings.allKeys(); for (const QString &key : allKeys) { qDebug().noquote() << key << "=" << settings.value(key).toString(); }组为General时:
localAddress = 192.168.68.1
localPort = 1235
peerAddress = 192.168.68.100
peerPort = 1234
组为info时:
info/localAddress = 192.168.68.1
info/localPort = 1235
info/peerAddress = 192.168.68.100
info/peerPort = 1234
总结
[General]是 QSettings 的约定,等同于"不属于任何组"的顶层键- 如果你需要统一用
"组名/键名"的方式访问,避免使用General作为组名,改用其他名称如[common]、[default]、[config]等即可