Qt读取ini格式配置文件的类设计

目录

1.引言

2.QSettings

2.1.功能特点

2.2.基本用法

3.读取ini文件配置通用类设计

3.1.设计要点

3.2.完整实现

3.3.调用方法

4.总结


1.引言

        在编写应用程序的时,有些参数需要用户配置,那么这些参数就涉及到存储了,单从存储来讲,就有很多实现的方案,比如ini格式文件保存、xml格式文件保存、json格式文件保存,数据库保存等,其中ini格式文件保存比较简单,也是平时项目用的比较多的一种,下面就详细讲讲Qt中读取ini格式配置文件的方法和通用类设计。

2.QSettings

        QSettings 是 Qt 框架中用于读取和写入应用程序配置信息的类。它提供了一个跨平台的解决方案,可轻松地保存和获取应用程序的设置和状态。

2.1.功能特点

1)跨平台支持:QSettings能够自动适配不同的操作系统,确保配置数据能在不同平台间无缝迁移。无论是Windows的注册表、macOS的plist文件,还是INI文件或JSON格式的文件,QSettings都能轻松处理。

2)键值对存储:使用键值对的方式来存储和读取应用程序的设置信息,使得配置数据的管理变得简单直观。

3)多种存储格式:支持多种存储格式,包括NativeFormat(使用操作系统推荐的存储方式)、IniFormat(将数据保存为INI格式的文本文件)和CustomFormat(允许指定自定义的存储格式,但需配合自定义的QSettings backend实现)。

4)默认值支持:在读取设置值时,如果找不到指定的键,QSettings可以返回预设的默认值。

5)辅助方法:提供了一些辅助方法来处理组织和应用程序范围的设置,以及检查设置是否存在、删除设置项等功能。

2.2.基本用法

创建QSettings对象

在使用 QSettings 之前,首先需要创建一个 QSettings 对象。可以通过以下两种方式进行初始化:

使用应用程序的组织名称和应用程序名称进行初始化:

QSettings settings("组织名称", "应用程序名称");

使用配置文件路径进行初始化:

QSettings settings("ConfigFile/config.ini", QSettings::IniFormat);

注意:如果没有指定配置文件路径,QSettings 将使用平台特定的位置存储配置信息。

存储设置值

使用 setValue() 函数可以将键值对存储到配置文件中:

settings.setValue("key", "value");

读取设置值

使用 value() 函数可以读取配置文件中的键对应的值:

QVariant value = settings.value("键");  
// 如果需要特定类型的值,可以使用如下方式:  
QString stringValue = settings.value("键").toString();  
int intValue = settings.value("键").toInt();

如果要指定默认值,可以在读取时提供:

QString username = settings.value("username", "DefaultUser").toString();

设置系统编码

当ini文件的内容中可能有中文,如果不设置编码,就可能出现乱码。

QSettings iniRead(file, QSettings::IniFormat);
iniRead.setIniCodec("utf-8"); //解决中文乱码的情况

检查设置是否存在

bool exists = settings.contains("键");

删除设置项

使用 remove() 函数可以删除配置文件中的指定键:

settings.remove("key");

持久化设置

在多线程环境中,如果需要确保数据立即写入持久存储,可以使用sync()方法:

settings.setValue("Setting1", "Value1");  
settings.sync(); // 强制立即写入

访问子组

settings.beginGroup("Window");  
settings.setValue("Width", 800);  
settings.endGroup(); // 可选,用于提高代码可读性

综合示例:

以下是一个使用QSettings保存和恢复窗口位置、大小等设置的示例:

#include <QApplication>  
#include <QMainWindow>  
#include <QSettings>  int main(int argc, char *argv[]) {  QApplication app(argc, argv);  QMainWindow window;  window.setWindowTitle("QSettings Example");  // Load settings  QSettings settings("YourCompany", "YourApp");  window.resize(settings.value("WindowSize", QSize(640, 480)).toSize());  window.move(settings.value("WindowPosition", QPoint(100, 100)).toPoint());  // Connect signals to save settings when necessary  QObject::connect(&window, &QMainWindow::windowStateChanged, [&settings](Qt::WindowState state) {  if (state == Qt::WindowMaximized)  settings.setValue("WindowState", "maximized");  else  settings.setValue("WindowState", "normal");  });  QObject::connect(&window, &QMainWindow::moveEvent, [&](QMoveEvent *event) {  settings.setValue("WindowPosition", event->pos());  });  QObject::connect(&window, &QMainWindow::resizeEvent, [&](QResizeEvent *event) {  settings.setValue("WindowSize", event->size());  });  window.show();  return app.exec();  
}

在这个示例中,我们创建了一个QSettings实例,并在窗口初始化时从其中加载先前保存的尺寸和位置。同时,连接了窗口状态变化、移动和调整大小的信号,以便在这些事件发生时自动更新存储的设置。

3.读取ini文件配置通用类设计

3.1.设计要点

1)应用程序用ini保存系统的配置,一般来说整个程序就一份,可以用单实例模式来实现整个类:

设计模式之单例模式-CSDN博客

class CShortWaveConfig
{
protected:CShortWaveConfig();~CShortWaveConfig();...public:static CShortWaveConfig& instance();....
};

2)普通的编程思路是一行一行得读取ini文件,然后分别保存到变量中,这样做不具有批量操性;转变一下思路,可以一次性把整个文件读取出来,保存到QMap中,关键代码如下:

class CShortWaveConfig
{
protected:bool loadConfig();。。。
private:QMap<QString, QVariant> m_value;
};bool CShortWaveConfig::loadConfig()
{。。。QStringList allKeys = iniRead.allKeys();for (auto& it : allKeys) {m_value[it] = iniRead.value(it);}return true;
}

3)元素的访问,每个元素的类型不知道,可利用C++中的模板把元素的类型T传入,判断是否可以从QVariant中的类型转换成T,关键代码如下:

template<typename T>
T value(const QString& key) {auto item = m_value.find(key);if (item != m_value.end()) {const QVariant& value1 = item.value();if (value1.canConvert<T>()) {return value1.value<T>();}assert(false);}。。。
}

4)元素的访问时,如果传入的路径找不到元素,可以返回默认参数,关键代码如下:

template<typename T>
T value(const QString& key, const T& defalutValue) {auto item = m_value.find(key);if (item != m_value.end()) {。。。}return defalutValue;
}

3.2.完整实现

ShortWaveConfig.h

#ifndef _SHORT_WAVE_CONFIG_H_
#define _SHORT_WAVE_CONFIG_H_
#include <QString>
#include <QMap>
#include <QVariant>
#include <assert.h>
using namespace std;class CShortWaveConfig
{
protected:CShortWaveConfig();~CShortWaveConfig();bool loadConfig();public:static CShortWaveConfig& instance();template<typename T>T value(const QString& key, const T& defalutValue) {auto item = m_value.find(key);if (item != m_value.end()) {const QVariant& value1 = item.value();if (value1.canConvert<T>()) {return value1.value<T>();}assert(false);}return defalutValue;}private:QMap<QString, QVariant> m_value;
};#endif

ShortWaveConfig.cpp

#include "ShortWaveConfig.h"
#include <QFile>
#include <QApplication>
#include <QSettings>CShortWaveConfig::CShortWaveConfig()
{bool result = loadConfig();assert(result);
}CShortWaveConfig::~CShortWaveConfig()
{}bool CShortWaveConfig::loadConfig()
{QString file = QCoreApplication::applicationDirPath() + "/systemConfig.ini";if (!QFile::exists(file)) {return false;}QSettings iniRead(file, QSettings::IniFormat);iniRead.setIniCodec("utf-8"); //解决中文乱码的情况QStringList allKeys = iniRead.allKeys();for (auto& it : allKeys) {m_value[it] = iniRead.value(it);}return true;
}CShortWaveConfig& CShortWaveConfig::instance()
{static CShortWaveConfig config;return config;
}

3.3.调用方法

//姓名
QString name = CShortWaveConfig::instance().value<QString>("Attr/name", "xiaoming");//年龄
int age = CShortWaveConfig::instance().value<int>("Attr/age", 20);

4.总结

        本文详细介绍了 Qt 中的 QSettings 类,包括初始化、读取、写入和删除配置信息的操作。还讲解了在整个系统中怎么去设计系统配置文件读取类CShortWaveConfig。通过合理使用类CShortWaveConfig,您可以轻松管理和存储应用程序的配置信息,提高应用程序的灵活性和可维护性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/40734.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

git 还原被删除的分支

在多人项目开发中&#xff0c;有一次碰到忘记合并到master分支了&#xff0c;直接就把开发分支给删除了&#xff0c;现在记录下怎么还原被删除的分支 必须保证删除的分支之前已经被推送到了远程仓库 # 找出被删除分支的最后一个提交的哈希值 git reflog show# 找到提交哈希值…

2024/07/04

1、梳理笔记(原创) 2、终端输入一个日期&#xff0c;判断是这一年的第几天 scanf("%d-%d-%d",&y,&m,&d); 闰年2月29天&#xff0c;平年2月28天 #include<stdio.h> int main(int argc, char const *argv[]) {int y0,m0,d0;printf("please ente…

析构函数和拷贝构造函数

文章目录 析构函数1.析构函数的定义&#xff1a;2.析构函数的语法&#xff1a;3.析构函数的特性&#xff1a; 拷贝构造函数1.拷贝构造函数的定义&#xff1a;2.拷贝构造函数的语法3.拷贝构造函数的特性(1)拷贝构造函数是构造函数的一个重载形式**(这个其实也很好理解&#xff0…

鸿蒙开发设备管理:【@ohos.thermal (热管理)】

热管理 该模块提供热管理相关的接口&#xff0c;包括热档位查询及注册回调等功能。 说明&#xff1a; 本模块首批接口从API version 8开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。开发前请熟悉鸿蒙开发指导文档&#xff1a;gitee.com/li-shi…

如何实现图片垂直旋转90度的问题

非常简单的问题&#xff0c;一串代码就可以解决。复制修改一下就可以直接使用&#xff0c;一个简单的小demo。写项目的时候需要写的功能&#xff0c;不到二十行代码就可以实现。 <html> <head><title>旋转图片</title><meta http-equiv"Conte…

Land survey boundary report (template)

Land survey boundary report (template) 土地勘测定界报告&#xff08;模板&#xff09;.doc

【高校科研前沿】南京地理与湖泊研究所博士后夏凡为第一作者在环境科学与水资源领域Top期刊发文:钙对云南洱海溶解有机质与浮游细菌相互作用的调控作用

文章简介 论文名称&#xff1a;Calcium regulates the interactions between dissolved organic matter and planktonic bacteria in Erhai Lake, Yunnan Province, China 第一作者及单位&#xff1a;夏凡&#xff08;博士后|中国科学院南京地理与湖泊研究所&#xff09; 通讯…

Git指令

一 参考&#xff1a;https://zhuanlan.zhihu.com/p/389814854 1.clone远程仓库 git clone https://git.xiaojukeji.com/falcon-mg/dagger.git 2.增加当前子目录下所有更改过的文件至index git add . 3.提交并备注‘xxx’ git commit -m ‘xxx’ 4.显示本地分支 git branch 5.显…

【pytorch13】激活函数及梯度

什么是激活函数 计算机科学家借鉴生物的神经元机制发明了计算机上的模型&#xff0c;这个模型与生物的神经元非常类似 激活的意思就是z变量要大于0&#xff0c;这一个节点才会激活&#xff0c;否则就会处于睡眠状态不会输出电平值 该激活函数在z0处不可导&#xff0c;因此不能…

Asp .Net Core 系列:基于 Castle DynamicProxy + Autofac 实践 AOP 以及实现事务、用户填充功能

文章目录 什么是 AOP &#xff1f;.Net Core 中 有哪些 AOP 框架&#xff1f;基于 Castle DynamicProxy 实现 AOPIOC中使用 Castle DynamicProxy实现事务管理实现用户自动填充 什么是 AOP &#xff1f; AOP&#xff08;Aspect-Oriented Programming&#xff0c;面向切面编程&a…

OpenCV——把YOLO格式的图片目标截图,并按目标类别保存

import os import cv2def get_class_folder(catagetory,class_id, base_folder):# 根据类别ID创建文件夹路径class_folder os.path.join(base_folder, catagetory[int(class_id)])if not os.path.exists(class_folder):os.makedirs(class_folder)return class_folderdef crop_…

VPN是什么?

VPN&#xff0c;全称Virtual Private Network&#xff0c;即“虚拟私人网络”&#xff0c;是一种在公共网络&#xff08;如互联网&#xff09;上建立加密、安全的连接通道的技术。简单来说&#xff0c;VPN就像是一条在公共道路上铺设的“秘密隧道”&#xff0c;通过这条隧道传输…

图像的反转

图像颜色的反转一般分为两种&#xff1a;一种是灰度图片的颜色反转&#xff0c;另一种是彩色图像的颜色反转。 本节使用的原图如下&#xff1a; 1.1 灰度图像颜色反转 灰度图像每个像素点只有一个像素值来表示&#xff0c;色彩范围在0-255之间&#xff0c;反转方法255-当前像…

信创产业政策,信创测试方面

信创产业的政策支持主要体现在多个方面&#xff0c;这些政策旨在推动产业的快速发展&#xff0c;加强自主创新能力&#xff0c;保障国家信息安全&#xff0c;以及促进产业结构的优化升级。 首先&#xff0c;政府通过财政支持、税收优惠等方式&#xff0c;加大对信创产业的资金…

8.ApplicationContext常见实现

ClassPathXmlApplicationContext 基于classpath下xml格式的配置文件来创建 <?xml version"1.0" encoding"UTF-8"?> <beans xmlns"http://www.springframework.org/schema/beans"xmlns:xsi"http://www.w3.org/2001/XMLSchema-i…

Flutter——最详细(Drawer)使用教程

背景 应用左侧或右侧导航面板&#xff1b; 属性作用elevation相当于阴影的大小 import package:flutter/material.dart;class CustomDrawer extends StatelessWidget {const CustomDrawer({Key? key}) : super(key: key);overrideWidget build(BuildContext context) {return…

解决SeaTunnel 2.3.4版本写入S3文件报错问题

在使用Apache SeaTunnel时&#xff0c;我遇到了一个写入S3文件的报错问题。通过深入调试和分析&#xff0c;找到了问题所在&#xff0c;并提出了相应的解决方案。 本文将详细介绍报错情况、参考资料、解决思路以及后续研究方向&#xff0c;希望对大家有帮助&#xff01; 一、…

代码随想录算法训练营第二天|【数组】977.有序数组的平方

题目 给你一个按 非递减顺序 排序的整数数组 nums&#xff0c;返回 每个数字的平方 组成的新数组&#xff0c;要求也按 非递减顺序 排序。 示例 1&#xff1a; 输入&#xff1a;nums [-4,-1,0,3,10] 输出&#xff1a;[0,1,9,16,100] 解释&#xff1a;平方后&#xff0c;数组…

修改头文件版本需要修改的文件

以修改ui的头文件版本为例&#xff0c;还需要同时更新 PJ10PC20240120041_c928\components\master-t5\hikauto\module\app\include PJ10PC20240120041_c928\components\master-t5\hikauto\module\app\include\dsp PJ10PC20240120041_c928\components\master-t5\hikauto\incl…

C# Halcon目标检测算法

在Halcon中进行目标检测可以使用传统的计算机视觉方法&#xff0c;也可以使用深度学习的方法。Halcon提供了丰富的函数库来处理这些任务&#xff0c;而在C#中使用Halcon&#xff0c;你需要通过Halcon .NET接口。 以下是使用Halcon进行目标检测的一般步骤&#xff0c;这里我将给…