QT 中使用 QSettings 读写 ini 配置文件

目录

前言

[一、QSettings 简介](#一、QSettings 简介)

[二、创建 QSettings 对象](#二、创建 QSettings 对象)

1.已知路径直接创建

[2. 未知路径先定义后创建](#2. 未知路径先定义后创建)

[三、QSettings 操作 ini 文件的基本原理](#三、QSettings 操作 ini 文件的基本原理)

[四、使用 QSettings 实现用户名和密码的增删改查功能](#四、使用 QSettings 实现用户名和密码的增删改查功能)

[1. 写入用户名和密码 (增加功能)](#1. 写入用户名和密码 (增加功能))

[2. 读取用户名和密码 (查询功能)](#2. 读取用户名和密码 (查询功能))

[3. 修改用户名和密码 (修改功能)](#3. 修改用户名和密码 (修改功能))

[4. 删除用户名和密码 (删除功能)](#4. 删除用户名和密码 (删除功能))

5.遍历用户列表

五、其它常用及注意事项

1.设置中文编码

2.按顺序读取列表

3.注意英文逗号存储

六、总结


前言

在 QT 应用程序开发过程中,经常需要对一些配置信息进行存储和读取,比如用户自定义的界面布局、程序运行参数等。ini 格式的配置文件因其简单直观、易于读写的特点,成为了常用的配置文件选择。而 QT 提供的QSettings类,为我们读写 ini 配置文件提供了便捷的接口。本文将详细介绍如何使用QSettings进行 ini 配置文件的读写操作。

一、QSettings 简介

QSettings类提供了一种跨平台的方式来读写应用程序的设置。它可以处理 ini 格式的配置文件,也支持其他平台特定的存储方式,如 Windows 的注册表。QSettings采用键值对的形式存储数据,类似于 QT中的QHash,​方便我们配置信息进行管理。​

二、创建 QSettings 对象

创建QSettings对象有两种方式。

1.已知路径直接创建

如果是已知ini文件路径,那么就可以在全局变量中直接创建QSettings对象。

cpp 复制代码
// 创建QSettings对象,指定ini文件路径和格式
QSettings settings("config.ini", QSettings::IniFormat);

上述代码中,第一个参数"config.ini"是 ini 文件的名称,如果文件不在当前工作目录,需要指定完整路径;第二个参数QSettings::IniFormat表示使用 ini 格式。

2. 未知路径先定义后创建

cpp 复制代码
(1)先在全局变量中声明QSettings指针
Qsettings *settings;

(2)在能获取到配置文件路径的函数中给sets赋值
delete settings;
settings=new Qsettings("config.ini",QSettings::IniFormat);

三、QSettings 操作 ini 文件的基本原理

QSettings 类提供了统一的接口来读写不同格式的配置文件,当使用 ini 格式时,它会自动处理 ini 文件的语法规则。

使用 QSettings 操作 ini 文件时,主要涉及以下几个方面:

  • 创建 QSettings 对象时指定 ini 文件路径
  • 使用 setValue () 方法写入键值对
  • 使用 value () 方法读取键值对
  • 支持分组 (节) 管理配置项

四、使用 QSettings 实现用户名和密码的增删改查功能

下面通过一个具体的示例来演示如何使用 QSettings 在 ini 文件中实现用户名和密码的增删改查功能。

1. 写入用户名和密码 (增加功能)

cpp 复制代码
#include <QCoreApplication>
#include <QSettings>
#include <QDebug>

// 保存用户名和密码到ini文件
void saveUserInfo(const QString &username, const QString &password)
{
    // 创建QSettings对象,指定ini文件路径和格式
    // 第一个参数是文件路径,第二个参数指定为IniFormat表示使用ini文件格式
    QSettings settings("config.ini", QSettings::IniFormat);
    
    // beginGroup()方法用于切换到指定的节(section)
    // 这里以用户名为节名,将该用户的所有信息存储在这个节下
    settings.beginGroup(username);
    
    // 使用setValue()方法写入键值对
    // 第一个参数是键名,第二个参数是值
    settings.setValue("password", password);
    
    // endGroup()表示结束当前节的操作
    // 与beginGroup()配对使用
    settings.endGroup();
    
    qDebug() << "用户信息已保存:" << username << " - " << password;
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    
    // 保存用户信息
    saveUserInfo("admin", "admin123");
    saveUserInfo("user1", "pass456");
    
    return a.exec();
}

上面的代码创建了一个 config.ini 文件,并在其中保存了两个用户的信息。生成的 ini 文件内容如下:

2. 读取用户名和密码 (查询功能)

cpp 复制代码
// 读取用户密码
QString getUserPassword(const QString &username)
{
    // 创建QSettings对象,指定要读取的ini文件
    QSettings settings("config.ini", QSettings::IniFormat);
    
    // 切换到指定用户节
    settings.beginGroup(username);
    
    // 使用value()方法读取键值
    // 第一个参数是键名,第二个参数是默认值
    // 当指定的键不存在时,返回默认值
    QString password = settings.value("password", "").toString();
    
    settings.endGroup();
    
    return password;
}

// 检查用户是否存在
bool checkUserExists(const QString &username)
{
    QSettings settings("config.ini", QSettings::IniFormat);
    
    // childGroups()方法返回所有节(section)的名称列表
    // 这里获取所有用户名
    QStringList users = settings.childGroups();
    
    // 检查指定用户名是否在列表中
    return users.contains(username);
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    
    // 检查用户是否存在并读取密码
    QString username = "admin";
    if (checkUserExists(username)) {
        QString password = getUserPassword(username);
        qDebug() << "用户" << username << "的密码是:" << password;
    } else {
        qDebug() << "用户" << username << "不存在";
    }
    
    return a.exec();
}

3. 修改用户名和密码 (修改功能)

cpp 复制代码
// 修改用户密码
bool modifyUserPassword(const QString &username, const QString &newPassword)
{
    // 先检查用户是否存在
    if (!checkUserExists(username)) {
        qDebug() << "用户" << username << "不存在,无法修改密码";
        return false;
    }
    
    // 存在则直接覆盖原密码
    // QSettings的setValue()方法在键已存在时会自动覆盖原值
    saveUserInfo(username, newPassword);
    qDebug() << "用户" << username << "的密码已修改为:" << newPassword;
    
    return true;
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    
    // 修改用户密码
    modifyUserPassword("admin", "newAdmin123");
    
    // 验证修改结果
    QString password = getUserPassword("admin");
    qDebug() << "修改后admin的密码是:" << password;
    
    return a.exec();
}

4. 删除用户名和密码 (删除功能)

cpp 复制代码
// 删除用户
bool deleteUser(const QString &username)
{
    QSettings settings("config.ini", QSettings::IniFormat);
    
    // 检查用户是否存在
    if (!checkUserExists(username)) {
        qDebug() << "用户" << username << "不存在,无法删除";
        return false;
    }
    
    // remove()方法用于删除指定的键或节
    // 当参数是节名时,会删除整个节及其下的所有键值对
    settings.remove(username);
    qDebug() << "用户" << username << "已删除";
    
    return true;
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    
    // 删除用户
    deleteUser("user1");
    
    // 验证删除结果
    if (checkUserExists("user1")) {
        qDebug() << "用户user1仍然存在";
    } else {
        qDebug() << "用户user1已成功删除";
    }
    
    return a.exec();
}

5.遍历用户列表

cpp 复制代码
QSettings usersettings("config.ini", QSettings::IniFormat);

// 获取所有用户列表
QStringList allUsers() {
    return usersettings.childGroups();
}

bool loadUsers(const QString& username, QString& password) {
    if (!usersettings.childGroups().contains(username))
        return false;

    usersettings.beginGroup(username);
    password = usersettings.value("Password").toString();
    usersettings.endGroup();
    return true;
}

int main(void){
    QString password;
    QStringList users = allUsers();
    for(int i=0;i<users.size();i++){
         QString user=users.at(i);
         loadUsers(user, password);
    }
} 

通过 usersettings.childGroups() ,可以获取到配置文件中所有[]的QStringList,然后通过username遍历就可以获取到用户信息的列表。

五、其它常用及注意事项

1.设置中文编码

cpp 复制代码
 usersettings.setIniCodec("UTF-8");

可以在创建对象后直接调用 setIniCodec("UTF-8"); 将读写编码格式改为 UTF-8。

2.按顺序读取列表

使用过QSettings的朋友应该知道,QSettings如果调用childGroups()函数,获取到的id的顺序不是配置文件中的顺序,而是通过二叉树排列的顺序,我们如果想按配置文件中的顺序读取内容,就需要费点事了。可以使用一个单独的分组存储id以及顺序,比如像下面这样。

对应的代码如下所示:

cpp 复制代码
// 全部变量信息
QStringList allVariables() {
    return variablesettings.value("Groups/__order").toStringList();
}

bool loadVariables(const QString& id, QString& description, QString& content) {
    if (!variablesettings.childGroups().contains(id))
        return false;

    variablesettings.beginGroup(id);
    description = variablesettings.value("Description").toString();
    content = variablesettings.value("Content").toString();
    variablesettings.endGroup();
    return true;
}

int main(void){
   QString description,content="";
   QStringList variables = allVariables();

    for(int i=0;i<variables.size();i++){
         QString id=variables.at(i);
         if(id!="Groups"){
             description="";
             content="";
             loadVariables(id, description, content);
         }
    }
}

我们把id以及顺序写到 Groups 下面的 __order 中,读取__order内容到QStringList中,然后根据QStringList遍历所有内容,这样顺序就是固定的了,这里还有个问题,就是得维护 __order,不然不统一就读不到所有内容了。

3.注意英文逗号存储

在配置文件中使用英文逗号存储会导致QSettings读出的内容和我们预定的不一致,除非是像QStringList那种 "1","2" 用双引号隔开的内容,如果我们需要隔开一条内容尽量用减号这些。

六、总结

通过 QSettings 类,我们可以方便地实现 ini 配置文件的读写操作,包括用户名和密码的增删改查功能。QSettings 提供了简洁的 API,使得配置文件的管理变得简单高效。在实际应用开发中,可以根据需要扩展这些基本功能,比如添加加密功能保护用户密码,或者实现更复杂的配置管理需求。

相关推荐
范纹杉想快点毕业1 小时前
Qt构造函数详解:布局与快捷键实战
c语言·开发语言·数据库·c++·qt·命令模式
iceslime1 小时前
数据分析和可视化:Py爬虫-XPath解析章节要点总结
开发语言·python
剽悍一小兔1 小时前
JDK24,他来了,抗量子加密
开发语言·python
Jerry404_NotFound1 小时前
求助帖:学Java开发方向还是网络安全方向前景好
java·开发语言·python·安全·网络安全·渗透·代码审计
勤奋的知更鸟1 小时前
Java 编程之代理模式
java·开发语言·设计模式·代理模式
YuTaoShao2 小时前
Java八股文——计算机网络「网络攻击篇」
java·开发语言·计算机网络
bubiyoushang8882 小时前
Kotlin中快速实现MVI架构
android·开发语言·kotlin
DBWYX3 小时前
PHP is the best language.
开发语言·php
何朴尧4 小时前
全局数据的处理
开发语言
Web极客码4 小时前
如何在中将网络改为桥接模式并配置固定IP地址
开发语言·网络·ubuntu·php·虚拟机