【Qt之QSetting】介绍及使用
概述
QSettings
类提供了一种持久的、与平台无关的应用程序设置存储功能。
用户通常期望一个应用能在不同会话中记住其设置(窗口大小和位置,选项等)。在Windows
上,这些信息通常存储在系统注册表中;在macOS
和iOS
上,存储在属性列表文件中;在Unix
系统上,由于缺乏标准,许多应用程序(包括KDE应用程序)使用INI文本文件。
QSettings
是对这些技术的抽象,在可移植性的基础上,使您能够保存和恢复应用程序设置。它还支持自定义的存储格式。
QSettings
的API基于QVariant
,允许您以最小的努力保存大多数基于值的类型,如QString、QRect和QImage等。
如果您只需要一个非持久的基于内存的结构,请考虑使用QMap<QString, QVariant>
替代。
基本用法
创建QSettings
对象时,必须传递您的公司
或组织的名称
以及应用程序的名称
。例如,如果您的产品名称为Star Runner,公司名为MySoft,您应该如下构造QSettings对象:
QSettings settings("MySoft", "Star Runner");
可以在堆上(使用new)或栈上创建QSettings
对象。构造和销毁QSettings
对象非常快速。
如果在应用程序的多个地方使用QSettings,可以使用QCoreApplication::setOrganizationName()
和QCoreApplication::setApplicationName()
来指定组织名称和应用程序名称,然后使用默认的QSettings
构造函数:
QCoreApplication::setOrganizationName("MySoft");
QCoreApplication::setOrganizationDomain("mysoft.com");
QCoreApplication::setApplicationName("Star Runner");
...
QSettings settings;
(这里还指定了组织的互联网域。在设置了互联网域的情况下,macOS和iOS会使用互联网域来标识应用程序,而不是组织名称,因为macOS和iOS应用程序通常使用互联网域来标识自己。如果未设置域,将从组织名称派生一个虚假的域。有关详细信息,请参阅下面的特定平台的注释。)
QSettings
存储设置。每个设置由一个QString(键)和一个QVariant(关联该键的数据)组成。使用setValue()来写入设置。例如:
settings.setValue("editor/wrapMargin", 68);
如果存在具有相同键的设置,新值将覆盖现有值。出于效率考虑,更改可能不会立即保存到永久存储中。(您可以随时调用sync()
来提交更改。)
使用value()方法可以获取设置的值:
int margin = settings.value("editor/wrapMargin").toInt();
如果没有指定名称的设置,QSettings将返回一个空的QVariant(可以转换为整数0)。您可以通过向value()传递第二个参数来指定另一个默认值:
int margin = settings.value("editor/wrapMargin", 80).toInt();
要测试给定键是否存在,请调用contains()
方法。要删除与键关联的设置,请调用remove()
方法。要获取所有键的列表,请调用allKeys()
方法。要删除所有键,请调用clear()
方法。
QVariant和GUI类型
由于QVariant
是Qt Core
模块的一部分,因此不能提供转换函数到Qt GUI
的数据类型,如QColor、QImage和QPixmap。换句话说,QVariant中没有toColor()、toImage()或toPixmap()等函数。
相反,您可以使用QVariant::value()
或qVariantValue()
模板函数。例如:
QSettings settings("MySoft", "Star Runner");
QColor color = settings.value("DataPump/bgcolor").value<QColor>();
反向转换(例如,从QColor到QVariant)对于QVariant支持的所有数据类型,包括与GUI相关的类型都是自动的:
QSettings settings("MySoft", "Star Runner");
QColor color = palette().background().color();
settings.setValue("DataPump/bgcolor", color);
使用qRegisterMetaType()
和qRegisterMetaTypeStreamOperators()
注册的自定义类型也可以使用QSettings进行存储。
部分和键的语法
设置键可以包含任何Unicode
字符。Windows
注册表和INI
文件使用不区分大小写的键,而macOS
和iOS
上的CFPreferences API
使用区分大小写的键。为了避免可移植性问题,请遵循以下简单规则:
- 始终使用相同的大小写引用相同的键。例如,如果在代码的某个地方将键称为
"text fonts"
,请不要在其他地方将其称为"Text Fonts"
。 - 避免只有大小写不同的键名称。例如,如果有一个名为
"MainWindow"
的键,请不要使用"mainwindow"
保存另一个键。 - 不要在部分或键名中使用斜线(‘/‘和’’)。反斜杠字符用于分隔子键(见下文)。在Windows上,‘‘会被QSettings转换为’/’,从而使它们相同。
您可以使用’/'字符作为分隔符来形成具有层次结构的键,类似于Unix文件路径。例如:
settings.setValue("mainwindow/size", win->size());
settings.setValue("mainwindow/fullScreen", win->isFullScreen());
settings.setValue("outputpanel/visible", panel->isVisible());
如果您想要保存或还原具有相同前缀的多个设置,可以使用beginGroup()
指定前缀,并在结束时调用endGroup()
。下面是相同的示例,但这次使用了组机制:
settings.beginGroup("mainwindow");
settings.setValue("size", win->size());
settings.setValue("fullScreen", win->isFullScreen());
settings.endGroup();settings.beginGroup("outputpanel");
settings.setValue("visible", panel->isVisible());
settings.endGroup();
如果使用beginGroup()
设置了组,大多数函数的行为会相应改变。组可以递归设置。
除了组,QSettings
还支持"数组"概念。详细信息请参阅beginReadArray()
和beginWriteArray()
。
后备机制
假设您已经创建了一个QSettings对象,组织名称为MySoft,应用程序名称为Star Runner。在查找值时,按照以下顺序搜索最多四个位置:
- Star Runner应用程序的特定用户位置
- 所有MySoft应用程序的特定用户位置
- Star Runner应用程序的系统范围位置
- 所有MySoft应用程序的系统范围位置
(有关Qt支持的不同平台上这些位置的信息,请参阅下面的特定平台的注释。)
如果在第一个位置找不到键,则继续在第二个位置搜索,依此类推。这使您能够存储系统范围或组织范围的设置,并可以在每个用户或每个应用程序的基础上进行覆盖。要关闭此机制,请调用setFallbacksEnabled(false)。
虽然可以从四个位置读取所有键,但只有第一个文件(与当前正在处理的应用程序相关的特定用户位置)可以写入。要写入其他文件,请省略应用程序名称和/或指定QSettings::SystemScope(与默认值QSettings::UserScope相对)。
让我们通过一个示例来看:
QSettings obj1("MySoft", "Star Runner");
QSettings obj2("MySoft");
QSettings obj3(QSettings::SystemScope "MySoft", "Star Runner");
QSettings obj4(QSettings::SystemScope, "MySoft");
下表总结了哪些QSettings对象访问哪些位置。"X"表示该位置是与QSettings对象关联的主位置,用于读取和写入;"o"表示在读取时该位置用作后备。
这种机制的美妙之处在于它适用于Qt支持的所有平台,并且仍然提供了很大的灵活性,而无需指定任何文件名或注册表路径。
如果您想在所有平台上都使用INI文件而不是本地API,可以将QSettings::IniFormat作为QSettings构造函数的第一个参数,后跟作用域、组织名称和应用程序名称:
QSettings settings(QSettings::IniFormat, QSettings::UserScope,"MySoft", "Star Runner");
Settings Editor示例允许您尝试不同设置位置以及打开或关闭后备机制。
恢复GUI应用程序的状态
QSettings经常用于存储GUI应用程序的状态。下面的示例演示了如何使用QSettings来保存和恢复应用程序主窗口的几何形状。
void MainWindow::writeSettings()
{QSettings settings("Moose Soft", "Clipper");settings.beginGroup("MainWindow");settings.setValue("size", size());settings.setValue("pos", pos());settings.endGroup();
}void MainWindow::readSettings()
{QSettings settings("Moose Soft", "Clipper");settings.beginGroup("MainWindow");resize(settings.value("size", QSize(400, 400)).toSize());move(settings.value("", QPoint(200, 200)).toPoint());settings.endGroup();
}
有关为什么调用QWidget::resize()
和QWidget::move()
而不是QWidget::setGeometry()
以恢复窗口的几何形状的讨论,请参阅窗口几何形状。
readSettings()
和writeSettings()
函数必须从主窗口的构造函数和close事件处理程序中调用,如下所示:
MainWindow::MainWindow()
{...readSettings();
}void MainWindow::closeEvent(QCloseEvent *event)
{if (userReallyWantsToQuit()) {writeSettings();event->accept();} else {event->ignore();}
}
有关使用QSettings的自包含示例,请参见Application示例。
同时从多个线程或进程访问设置
QSettings
是可重入的。这意味着可以同时在不同的线程中使用不同的QSettings
对象。即使这些QSettings
对象引用相同的磁盘文件(或系统注册表中的相同条目),此保证仍然有效。如果通过一个QSettings
对象修改了一个设置,这个更改将立即对在同一位置操作并且在同一进程中存在的任何其他QSettings
对象可见。
可以安全地从不同的进程(可以是同时运行的应用程序的不同实例或完全不同的应用程序)读取和写入相同的系统位置。它使用建议性文件锁定和智能合并算法来确保数据的完整性。请注意,sync()方法会导入其他进程所做的更改(除了写入这个QSettings的更改)。
常用方法
以下是QSettings类的一些常用方法的介绍。
构造函数:
QSettings(const QString& organization, const QString& application = QString(), QObject *parent = nullptr)
- 使用组织名称和应用程序名称创建一个QSettings对象。默认情况下,QSettings使用基于平台的本地存储机制。
- organization:组织名称
- application:应用程序名称(可选)
- parent:父级QObject对象(可选)
读取和写入值:
value(const QString& key, const QVariant& defaultValue = QVariant())
:读取指定键的值,如果键不存在则返回defaultValue。返回QVariant类型的值。setValue(const QString& key, const QVariant& value)
:设置指定键的值。remove(const QString& key)
:删除指定键及其对应的值。clear()
:清除所有的设置键和值。
设置默认值:
setDefaultFormat(QSettings::Format format)
:为所有新创建的QSettings对象设置默认格式(例如,INI格式或注册表格式)。setDefaultScope(QSettings::Scope scope)
:为所有新创建的QSettings对象设置默认作用域(用户范围或系统范围)。
读取和写入组:
beginGroup(const QString& prefix)
:开始一个以prefix为前缀的设置组。endGroup()
:结束当前的设置组。
同步操作:
sync()
:将所有的更改写入到永久存储,确保数据的同步。通常,QSettings会自动定期执行这个操作,但在某些情况下可能需要手动调用。
获取设置信息:
fileName()
:返回与当前QSettings对象关联的文件名。scope()
:返回当前QSettings对象的作用域(用户范围或系统范围)。organizationName()
:返回当前QSettings对象的组织名称。applicationName()
:返回当前QSettings对象的应用程序名称。
注意:QSettings
还提供了其他一些方法,例如支持跨线程和进程读写设置,以及对设置键和值进行迭代和查询。
示例
以下是一个使用QSettings的示,包含了常用的成员方法:
#include <QCoreApplication>
#include <QSettings>
#include <QDebug>int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);// 创建 QSettings 对象QSettings settings("MyCompany", "MyApp");// 设置值settings.setValue("username", "John");settings.setValue("password", "123456");// 获取值QString username = settings.value("username").toString();QString password = settings.value("password").toString();qDebug() << "Username:" << username;qDebug() << "Password:" << password;// 检查是否存在某个键if (settings.contains("username")) {qDebug() << "The 'username' key exists";}// 移除一个键settings.remove("password");// 通过分组设置值,创建一个新的分组settings.beginGroup("Server");settings.setValue("host", "localhost");settings.setValue("port", 8080);settings.endGroup();// 在分组中获取值QString serverHost = settings.value("Server/host").toString();int serverPort = settings.value("Server/port").toInt();qDebug() << "Server Host:" << serverHost;qDebug() << "Server Port:" << serverPort;// 将更改刷新到磁盘上的配置文件中settings.sync();return a.exec();
}
结果
示例步骤:
- 创建了一个名为"MyApp"的应用程序设置,并设置了一些值。
- 通过value()方法获取这些值并输出。使用contains()方法检查特定的键是否存在,并使用remove()方法移除了"password"键。
- 使用beginGroup()和endGroup()方法创建了一个名为"Server"的分组,并在该分组中设置了一些值。
- 通过sync()方法将更改刷新到配置文件中。
相关文章:

【Qt之QSetting】介绍及使用
概述 QSettings类提供了一种持久的、与平台无关的应用程序设置存储功能。 用户通常期望一个应用能在不同会话中记住其设置(窗口大小和位置,选项等)。在Windows上,这些信息通常存储在系统注册表中;在macOS和iOS上&…...

基于WebRTC构建的程序因虚拟内存不足导致闪退问题的排查以及解决办法的探究
目录 1、WebRTC简介 2、问题现象描述 3、将Windbg附加到目标进程上分析 3.1、Windbg没有附加到主程序进程上,没有感知到异常或中断 3.2、Windbg感知到了中断,中断在DebugBreak函数调用上 3.3、32位进程用户态虚拟地址和内核态虚拟地址的划分 …...

通过jdk自制https证书并配置到nginx并配置http2
生成证书 这里使用自己生成的免费证书。在${JAVA_HOME}/bin 下可以看到keytool.exe,在改目录打开cmd然后输入: keytool -genkey -v -alias lgq.com -keyalg RSA -keystore d:/zj/ssl/fastfly.com.keystore -validity 3650生成证书过程中:【你的名字】对…...

祝贺中国煤科重庆研究院和达索、百世慧PLM项目顺利结项
引言 2023年10月17日,中国煤科重庆研究院与达索系统、百世慧在重庆研究院会议室召开了产品全生命周期管理(PLM)系统结项会。中国煤科重庆研究院科技发展部副主任孙海涛、测控技术研究分院副院长于庆、重庆大学教授鄢萍、达索公司工业装备部南…...

基于springboot实现数码论坛系统设计与实现系统【项目源码+论文说明】
基于springboot实现数码论坛系统设计与实现系统演示 摘要 网络的广泛应用给生活带来了十分的便利。所以把数码论坛与现在网络相结合,利用java技术建设数码论坛系统,实现数码论坛的信息化。则对于进一步提高数码论坛发展,丰富数码论坛经验能起…...

魔域开服需要什么样的配置
魔域是一个非常受玩家喜欢的游戏,是一款大型魔幻题材的网络游戏,关于魔族入侵亚特大陆的故事,玩家在游戏里扮演不同的角色捍卫大陆安全,很多玩家想要更多的体验就会选择开新服,今天就让小编来讲一讲魔域开服要什么配置…...

7个好用的PC端设计软件,设计必看!优漫动游
身为设计师的你是不是还在为到处寻找合适的设计软件而烦恼?是不是在为因为没能用上好的软件而影响自己设计生涯的事情感到焦虑?别担心,你的烦恼可能每个成熟的设计师都遇到过,但他们最终都走了过来。借助以下7个好用的PC端设计软件…...

10-动画animation
动画animation 动画-过渡和动画之间的异同-animation-name 指定要绑定到选择器的关键帧的名称,告诉系统需要执行哪个动画-animation-duration 动画指定需要多少秒或毫秒完成,告诉系统动画持续的时长-animation-timing-function 设置动画将如何完成一个周…...

【带头学C++】----- 1.基础知识 ---- 1.24 逻辑控制语句
1.24 逻辑控制语句 本节主要学习关于C逻辑控制的一些语句的用法,结合实践代码总结一下。 1.24.1 if以及if - else(条件语句) 1.if语句: if(条件){执行语句; }//一旦执行if语句,先判断()里的条件是否满足,…...

微信公众号分销商城源码系统+多元商家+收银台 带完整的搭建教程
给大家推荐一款微信公众号分销商城源码系统,这是一个全新三级分销商城,功能十分丰富。一起来看看你吧。 微信公众号分销商城的功能: 1.商品展示和推广:商家可以在商城中展示商品信息,包括商品名称、价格、库存等&#…...

排序算法:选择排序,分别用c++、java、python实现
选择排序介绍 选择排序(Selection Sort)是一种简单的比较排序算法,它的工作原理如下: 分区: 将待排序的数组分成两个部分,一个部分是已排序的子数组,另一个部分是未排序的子数组。初始时,已排序…...

支付宝支付接入流程
一、 接入准备 支付宝支付流程没有微信那么复杂,而且支付宝支持沙箱。登录支付宝开放平台控制台 点击开发工具中的沙箱 接口加密方式,我这里使用的是自定义密钥。生成密钥的方式 使用支付宝官方提供的密钥工具,唯一要注意的是支付宝密钥工具…...

管理员|顾问必看!8个Salesforce权限集的最佳实践
Salesforce中的权限一直始终是热门话题。权限集是简档的附加。它们通常具有相同的设置,用于增加用户的权限,使其超过简档提供的权限。可以将简档视为许多用户共有的基本权限集,而权限集是部分用户需要的额外权限。 本篇文章将介绍Salesforce…...

【linux进程(六)】环境变量再理解程序地址空间初认识
💓博主CSDN主页:杭电码农-NEO💓 ⏩专栏分类:Linux从入门到精通⏪ 🚚代码仓库:NEO的学习日记🚚 🌹关注我🫵带你学更多操作系统知识 🔝🔝 程序地址空间 1. 前言2. 在ba…...

10步开启SAFe敏捷发布列车
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 敏捷畅想一、培训 SAFe 项目顾问 (SPC)二、培训精益敏捷领导者三、 举办价值流研讨会并确定您的第一个敏捷发布系列四、 定义/设置 ART 和团队五、 担任重要角色六、…...

面试题之Vue和React的区别是什么?
一提到前端框架,相信大家都对Vue和React不陌生,这两个前端框架都是比较主流的,用户也都比较多,但是我们在使用这些框架的时候,是否对这两个框架之间的区别有所了解呢?接下来,让我们来一起的系统…...

Linux基础知识——概述和常用文件管理命令
Linux基础知识——概述和常用文件管理命令 文章目录 Linux基础知识——概述和常用文件管理命令概述常用的一些文件指令 概述 终端:一个terminal窗口就是以个屏幕, 远程连接了一个服务器, 每一个terminal可以连接到任何一个其他服务器上;关掉terminal相当于只是关掉…...

腾讯云创建了jenkins容器,但无法访问
1、首先,查看本机能不能ping通你的腾讯云服务器 如果ping的通那就下一步 2、查看腾讯云服务器的防火墙关了没,没关关掉、 firewall-cmd --state not running 3、那就在云服务器的控制台开放端口...

C语言的const函数修饰指针
文章目录 一、const函数的作用 int a 10; int *p ; p &a;从上面的代码分析,p 存放的就是a的地址, *p 存放的就是 a 的值。 一、const函数的作用 一旦使用了const函数修饰一个变量,那么这个变量就无法变化了。 所以下面三种情况&#…...

EasyExcel使用方式(包含导出图片)
1、导EasyExcel依赖 <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.3.2</version> </dependency> 2、创建导出excel的实体类 Getter Setter EqualsAndHashCode HeadStyle(fillF…...

redis学习(三)——java整合redis
Jedis Jedis可以用于java连接redis数据库 新建一个maven项目,导入Jedis依赖 <dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter</artifactId><version>RELEASE</version><scope>test…...

OpenText 安全取证软件——降低成本和风险的同时,简化电子取证流程
OpenText 安全取证软件,行业标准的数字调查解决方案,适用于各种规模和各种行业的组织 降低成本和复杂性 • 远程调查比轮流调查过程更有效 对结果持有信心 • 磁盘级可见性可以完成相关端点数据的搜索和收集 谨慎调查 • 完整的网络调查…...

【vue】vue前端、生产(线上)环境请求unicloud云服务空间axios报错
目录 原因总结:借助Nginx使得axios可跨域请求 原因 使用axios的时候,如果是开发环境下,WebStorm(IDEA)会自带跨域功能,说白了就是不用考虑跨域的事情了。但是在生产环境下,vue前端编译成静态文…...

JVM详解(InsCode AI 创作助手)
JVM是一个虚拟的计算机,它有自己的硬件架构,如处理器、堆栈和寄存器等,也有自己的指令系统。JVM的主要任务是负责加载、验证、编译和执行Java程序。 一、JVM参数默认配置如下 内存设置: 初始堆内存大小:物理内存的1/…...

华为c语言编程规范
提示:附件为编程规范 文章目录 前言一、华为c语言编程规范总结 前言 例如:华为规范下载 一、华为c语言编程规范 该处使用的url网络请求的数据。 总结 提示:这里对文章进行总结: 例如:以上就是今天要讲的内容…...

SQL Server Management Studio (SSMS)的安装教程
文章目录 SQL Server Management Studio (SSMS)的安装教程从Microsoft官网下载SQL Server Management Studio安装程序。选中安装程序右键并选择“以管理员的身份运行”选项选择安装目录,单击“安装”按钮开始安装过程安装成功界面安装完成后,您可以启动S…...

React 图片瀑布流
思路: 根据浏览器宽度,确定列数,请求的图片列表数据是列数的10倍,按列数取数据渲染 Index.js: import React from react import { connect } from react-redux import { withRouter } from react-router-dom import { SinglePag…...

C++数据结构X篇_21_插入排序(稳定的排序)
文章目录 1. 插入排序原理2. 算法图解3. 核心代码:4. 插入排序整体代码实现 1. 插入排序原理 插入排序是一种最简单直观的排序算法,它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相…...

【Unity】3D跑酷游戏
展示 finish_all * 方块跑酷 1.教程链接 翻墙:https://www.youtube.com/watch?v9ZEu_I-ido4&listPLPV2KyIb3jR53Jce9hP7G5xC4O9AgnOuL&index3 2.基础制作 最终成果 2.1 基本场景 1.创建Cube作为跑道 1)记得把位置Reset; 2&#…...

bp前端验证码绕过及token绕过
前端验证码绕过及token绕过 原文参考:xiu 文章目录 前端验证码绕过及token绕过原文参考:[xiu](http://www.xiusafe.com/2023/10/25/%E9%AA%8C%E8%AF%81%E7%A0%81%E7%BB%95%E8%BF%87/)1 验证码爆破1. 登录Pikachu,先获取登录的api接口2 验证码…...