目录
[一、QSettings 简介](#一、QSettings 简介)
[二、创建 QSettings 对象](#二、创建 QSettings 对象)
[2. 未知路径先定义后创建](#2. 未知路径先定义后创建)
[三、QSettings 操作 ini 文件的基本原理](#三、QSettings 操作 ini 文件的基本原理)
[四、使用 QSettings 实现用户名和密码的增删改查功能](#四、使用 QSettings 实现用户名和密码的增删改查功能)
[1. 写入用户名和密码 (增加功能)](#1. 写入用户名和密码 (增加功能))
[2. 读取用户名和密码 (查询功能)](#2. 读取用户名和密码 (查询功能))
[3. 修改用户名和密码 (修改功能)](#3. 修改用户名和密码 (修改功能))
[4. 删除用户名和密码 (删除功能)](#4. 删除用户名和密码 (删除功能))
前言
在 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,使得配置文件的管理变得简单高效。在实际应用开发中,可以根据需要扩展这些基本功能,比如添加加密功能保护用户密码,或者实现更复杂的配置管理需求。