Qt 5.12中使用QSettings写ini文件如何让section与键名正确显示UTF-8中文
原因说明
Qt 5版本中QSettings的默认Ini格式读写逻辑存在设计限制:setIniCodec()方法仅作用于键值的编码解析/写入,分组(section)、键名的非ASCII字符会被强制转义为%UXXXX的Unicode转义格式,不受INI编码设置影响。
可行解决方案
方案1:自定义Ini读写逻辑(适配Qt 5全版本,无需升级Qt)
通过QSettings::registerFormat()注册自定义的INI格式读写函数,覆盖Qt默认的转义逻辑,实现分组、键名直接写入UTF-8字符,代码示例如下:
// 自定义INI写函数 bool writeUtf8Ini(QIODevice &device, const QSettings::SettingsMap &map) { QTextStream out(&device); out.setCodec("UTF-8"); QString currentGroup; for (auto it = map.constBegin(); it != map.constEnd(); ++it) { QString key = it.key(); int slashPos = key.indexOf('/'); QString group = slashPos > 0 ? key.left(slashPos) : QString(); QString subKey = slashPos > 0 ? key.mid(slashPos + 1) : key; // 写入分组头 if (group != currentGroup) { out << "[" << group << "]\n"; currentGroup = group; } // 写入键值对,特殊字符可按需添加转义逻辑 out << subKey << "=" << it.value().toString() << "\n"; } out.flush(); return true; } // 自定义INI读函数 bool readUtf8Ini(QIODevice &device, QSettings::SettingsMap &map) { QTextStream in(&device); in.setCodec("UTF-8"); QString currentGroup; while (!in.atEnd()) { QString line = in.readLine().trimmed(); if (line.isEmpty() || line.startsWith(';')) continue; // 跳过空行、注释 // 匹配分组 if (line.startsWith('[') && line.endsWith(']')) { currentGroup = line.mid(1, line.size() - 2).trimmed(); continue; } // 匹配键值对 int equalPos = line.indexOf('='); if (equalPos < 0) continue; QString key = line.left(equalPos).trimmed(); QString value = line.mid(equalPos + 1).trimmed(); if (!currentGroup.isEmpty()) { key = currentGroup + "/" + key; } map.insert(key, value); } return true; } // 注册自定义格式,只需要在程序初始化时调用一次 void registerUtf8IniFormat() { const QSettings::Format utf8IniFormat = QSettings::registerFormat( "ini", readUtf8Ini, writeUtf8Ini, Qt::CaseInsensitive ); }
使用时直接用注册后的格式创建QSettings即可:
// 先调用一次注册函数(程序启动时执行一次即可) registerUtf8IniFormat(); // 后续使用示例 QSettings setting("xxx.ini", QSettings::registeredFormat("ini")); setting.beginGroup(u8"运动控制器"); setting.setValue(u8"运动控制器", u8"运动控制器"); setting.endGroup();
注:以上示例为简化实现,若业务中存在键名包含=、[]、换行等特殊字符的场景,可自行补充对应的转义/反转义逻辑。
方案2:升级Qt版本
若项目可升级Qt到6.1及以上版本,直接使用Qt新增的QSettings::Utf8IniFormat格式即可,无需额外自定义逻辑:
QSettings setting("xxx.ini", QSettings::Utf8IniFormat); // 后续读写逻辑和原来一致即可
内容的提问来源于stack exchange,提问作者Qingguo Hu
相关产品推荐
相关产品推荐

