You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 21:21:01