QSettings读写注册表、配置文件

简述

一般情况下,我们在开发软件过程中,都会缓存一些信息到本地,可以使用轻量级数据库sqlite,也可以操作注册表、读写配置文件。

关于QSettings的使用前面已经介绍过了,比较详细,见“更多参考”,下面介绍下QSettings常用功能-读写注册表、配置文件。

  • 简述
  • 优点
  • 读写注册表
    • 一般存储
    • 一般读取
    • 分目录存储
      • 替换applicationName
      • 分组
  • 读写配置文件
    • 一般存储
    • 一般读取
    • 分组存储
    • 分组读取
    • 分目录存储
  • 删除内容
  • 疑问解释
  • 更多参考

优点

无需指定注册表路径

一般情况下,我们需要定义一个宏,或者常量字符串来指定保存的注册表位置。

  • #define HKEY_CURRENT_USER_QT "HKEY_CURRENT_USER\\SoftWare\\Digia\\Qt"
  • const QString HKEY_CURRENT_USER_QT = "HKEY_CURRENT_USER\\SoftWare\\Digia\\Qt";

无需指定配置文件路径

一般情况下,我们需要定义一个宏,或者常量字符串来指定保存的配置文件位置及名称。

  • #define INI_QT "C:\Users\WangLiang\AppData\Roaming\Digia"
  • const QString INI_QT = "C:\Users\WangLiang\AppData\Roaming\Digia";

采用下面方式,我们不需要做太多工作,Qt已经很好的替你实现了!

读写注册表

一般存储

下面我们以Qt为例,众所周知现在Qt已经属于Digia,也就是说:组织名为Digia,产品名为Qt。

在main()函数中,首先设置组织名、产品名。

QCoreApplication::setOrganizationName(QString("Digia"));
QCoreApplication::setApplicationName(QString("Qt"));

然后使用QSettings对注册表进行操作:

QSettings settings(QSettings::NativeFormat, QSettings::UserScope, QCoreApplication::organizationName(), QCoreApplication::applicationName());

settings.setValue("Name", "Qt Creator");
settings.setValue("Version", 5);

这时,我们打开注册表regedit,数据就生成了。

一般读取

存储完数据之后,默认的程序启动时需要加载对应的数据。

QString strName = settings.value("Name").toString();
int nVersion = settings.value("Version").toInt();
//Name:Qt Creator  Version:5

这时,我们可以通过查看应用程序输出窗口得到输出结果。

分目录存储

如果我们需要在同一路径下建立多个子目录该怎么办,下面介绍两种方式。

替换applicationName

如上,我们可以看出,organizationName对应的注册表路径为HKEY_CURRENT_USER\\SoftWare\\Digia,applicationName对应的为其下一级的目录,那么分目录就需要更改其对应的applicationName。

QSettings settings(QSettings::NativeFormat, QSettings::UserScope, QString("%1\\%2").arg(QCoreApplication::organizationName()).arg(QCoreApplication::applicationName()), "Qt5.5");

settings.setValue("Name", "Qt Creator");
settings.setValue("Version", "5.5");

QSettings settings2(QString("%1\\%2").arg(QCoreApplication::organizationName()).arg(QCoreApplication::applicationName()), "Qt5.6");

settings2.setValue("Name", "Qt Creator");
settings2.setValue("Version", "5.6");

分组

替换applicationName的方式看起来有些繁琐,相比之下,使用group分组则会更简单!

QSettings settings;
settings.beginGroup("Qt5.5");
settings.setValue("Name", "Qt Creator");
settings.setValue("Version", "5.5");
settings.endGroup();

settings.beginGroup("Qt5.6");
settings.setValue("Name", "Qt Creator");
settings.setValue("Version", "5.6");
settings.endGroup();

这时,我们再次查看注册表数据。

注:
新建目录,则需要重新打开注册表,如果新添加设置,则不需要重新打开注册表,只需要来回切换对应的选项即可。

读写配置文件

一般存储

如上,我们只需要将格式从NativeFormat变为IniFormat即可:

QSettings settings(QSettings::IniFormat, QSettings::UserScope, QCoreApplication::organizationName(), QCoreApplication::applicationName());

settings.setValue("Name", "Qt Creator");
settings.setValue("Version", 5);

这时,我们打开对应的存储目录,数据就生成了。

我们可以进入文件夹:C:\Users\WangLiang\AppData\Roaming(AppData默认为隐藏文件,需要设置显示才可查看),可以看到生成了文件夹”Digia”以及配置文件”Qt.ini”。

一般读取

存储完数据之后,默认的程序启动时需要加载对应的数据。

QString strName = settings.value("Name").toString();
int nVersion = settings.value("Version").toInt();
//Name:Qt Creator  Version:5

这时,我们可以通过查看应用程序输出窗口得到输出结果。

分组存储

我们可以看到配置文件中包含默认的分组为:General。通常情况下,我们需要对配置进行归类,例如:用户名、密码等信息属于用户组,产品名称、版本号属于设置组。

QSettings settings(QSettings::IniFormat, QSettings::UserScope, QCoreApplication::organizationName(), QCoreApplication::applicationName());

settings.beginGroup("Setting");
settings.setValue("Name", "Qt Creator");
settings.setValue("Version", 5);
settings.endGroup();

settings.beginGroup("User");
settings.setValue("UserName", "WangL");
settings.setValue("Password", "123456");
settings.endGroup();

这时我们再次查看配置文件,里面已经生成了另外两个分组。

分组读取

settings.beginGroup("Setting");
QString strName = settings.value("Name").toString();
int nVersion = settings.value("Version").toInt();
settings.endGroup();
//Name:Qt Creator  Version:5

settings.beginGroup("User");
QString strUserName = settings.value("UserName").toString();
QString strPassword = settings.value("Password").toString();
settings.endGroup();
//UserName:WangL  Password:123456

分目录存储

什么时候需要分目录存储呢?QQ大家都用过吧,是不是每一个用户都有一个对应QQ号的目录呢,里面保存各个用户对应的信息。

如上,我们可以看出,organizationName对应的本地路径为C:\Users\WangLiang\AppData\Roaming\Digia,applicationName对应的为其下的配置文件,那么如果我们需要在同一路径下建立多个目录就需要更改对应的organizationName,配置文件名称则需要更改其对应的applicationName了。

QSettings settings(QSettings::IniFormat, QSettings::UserScope, QString("%1\\%2\\%3").arg(QCoreApplication::organizationName()).arg(QCoreApplication::applicationName()).arg("Qt5.5"), "User");
settings.setValue("Name", "Qt Creator");
settings.setValue("Version", "5.5");

QSettings settings2(QSettings::IniFormat, QSettings::UserScope, QString("%1\\%2\\%3").arg(QCoreApplication::organizationName()).arg(QCoreApplication::applicationName()).arg("Qt5.5"), "User");
settings2.setValue("Name", "Qt Creator");
settings2.setValue("Version", "5.6");

这时,我们再次查看本地文件,则会发现C:\Users\WangLiang\AppData\Roaming\Digia\Qt所在目录下会生成两个文件夹”Qt5.5”和”Qt5.6”,并且每一个目录底下会生成对应的配置文件User.ini。

删除内容

删除一个指定的键

QSettings settings;
settings.setValue("Name", "Qt Creator");
settings.setValue("Version", 5);

settings.remove("Name");

QStringList keys = settings.allKeys();
// keys: ["Version"]

清空所有键

settings.clear();
QStringList keys = settings.allKeys();
// keys: []

删除设置键以及子设置键

QSettings settings;
settings.setValue("Qt5.6", "5.6");

settings.beginGroup("Qt5.5");
settings.setValue("Name", "Qt Creator");
settings.setValue("Version", "5.5");
settings.endGroup();

settings.beginGroup("Qt5.6");
settings.setValue("Name", "Qt Creator");
settings.setValue("Version", "5.6");
settings.endGroup();

settings.remove("Qt5.6");

QStringList strList = settings.allKeys();
// keys: ["Qt5.5/Name", "Qt5.5/Version"]

如果key为空字符串,在当前group()的所有键将被删除。

QSettings settings;
settings.setValue("Qt5.6", "5.6");

settings.beginGroup("Qt5.5");
settings.setValue("Name", "Qt Creator");
settings.setValue("Version", "5.5");
settings.endGroup();

settings.beginGroup("Qt5.6");
settings.setValue("Name", "Qt Creator");
settings.setValue("Version", "5.6");
settings.endGroup();

settings.beginGroup("Qt5.6");
settings.remove("");
settings.endGroup();

QStringList keys = settings.allKeys();
// keys: ["Qt5.5/Name", "Qt5.5/Version"]

疑问解释

如上文代码,我们可以知道未删除之前keys: ["Qt5.6", "Qt5.5/Name", "Qt5.5/Version", "Qt5.6/Name", "Qt5.6/Version"],其中Qt5.6所在分组为默认的General。

那么调用下面代码:

settings.beginGroup("Qt5.6");
settings.remove("");
settings.endGroup();

应该只删除对应组中的所有键才对,也就是说剩余的keys应该为 ["Qt5.6", "Qt5.5/Name", "Qt5.5/Version"],General下的键为什么会被删除呢?好,这里先跳过,继续。

General下的键既然可以被删除,那么在Qt5.5分组下建立对应的Qt5.6键值,应该也会被删除。

删除前:

删除后:

什么鬼,为嘛Qt5.5分组下的Qt5.6对应的键还在呢?

我们继续分析:

删除前:keys: ["Qt5.6", "Qt5.5/Qt5.6", "Qt5.5/Name", "Qt5.5/Version", "Qt5.6/Name", "Qt5.6/Version"]

助手中关于remove()的说明为:Removes the setting key and any sub-settings of key.

也就是说:Qt5.5/Qt5.6键中即使存在Qt5.6,但是所属的setting key为Qt5.5而非Qt5.6,所以不会被删掉。

既然这样,那么我们的疑问也就不复存在了。

更多参考

时间: 2024-11-02 14:54:24

QSettings读写注册表、配置文件的相关文章

WinCE下读写注册表的又一种方法

      上一篇介绍了VB.NET读写WinCE注册表的方法,用着确实方便.在驱动或者应用程序开发的过程中,其实也有一种简便的方法读写注册表,使用微软提供的CReg类(Registry helper class).用法也很简单,只要包括creg.hxx即可,SDK中一般会包含该头文件.       闲话少说,直接附上代码,供参考.   1 // Preloader.cpp : 定义控制台应用程序的入口点.  2 //  3   4 #include "stdafx.h"  5 #in

WinCE下VB.NET读写注册表的参考代码

      与桌面Windows系统类似,WinCE将有关操作系统.应用程序和驱动的设置信息都保存在系统注册表中.WinCE的注册表与桌面系统中的组织方式也差不多,包括了如下四个根键:       HKEY_CLASS_ROOT,包含了文件扩展名信息和COM子系统的配置信息       HKEY_LOCAL_MACHINE,包含了系统.驱动和应用程序的配置信息       HKEY_CURRENT_USER,包含了当前用户的配置信息       HKEY_USER,包含了所有用户的信息     

C#读写注册表

注册表 C#编程打造自己的IE浏览器 选择自 yudehui 的 Blog 关键字 C#编程打造自己的IE浏览器 出处 声明:本文已经放到了天极网站上,这里只是收藏而已.未经许可,不得转载 IE是现在Windows平台下用的最多的浏览器,那么如何用程序来修改IE,打造有自己的特色的IE呢? 我在这里向介绍怎么C#用通过注册表来修改IE. 首先我们来熟悉一下C#中修改注册表的方法与函数.在VC#中提供了Registry类.RegistryKey类来实现对注册表的操作.其中Registry类封装了注

一个简单的读写注册表实例

一.说明: 注册表是Windows重要组成部分,注册表记录了大量有关电脑软硬件的信息.注册表中的值通过其名称标识.值名称由与键名相同的字符组成.值本身可以是字符串.二进制数据或者是32位无符号值.在这里我们主要运用以下技巧: (一).预定义的注册表键.注册表包含了几个预定义键: HKEY_LOCAL_MACHINE 包含描述计算机及其配置的条目.其中包括关于处理器.系统主板.内存和已安装的软件和硬件的信息. HKEY_CLASSES_ROOT 是与文档类型和 OLE\COM 相关的信息的支持键.

分享关于JAVA 中使用Preferences读写注册表时要注意的地方_java

要注意的只有一个地方,那就是键名或者项名不要包含大写字母,否则读不到数据. 代码是这样的: 复制代码 代码如下: Preferences preferences = Preferences.systemRoot();String strRegTime = preferences.get("regTime", ""); 注册表中是这样的 不论怎么改都读不到regTime的值.后来想到现在代码中把值写进去看看是什么样的,代码如下 复制代码 代码如下: Preferenc

64位系统中读写注册表

在群里下载了一个CAD自动加载.NET程序源码程序.先在64位系统中运行了,不能读取当前CAD版本及已加载的.NET程序集.加了try调试,问题在于registry.localmachine.opensubkey永远返回的是Null.所以-- 百度了没有发现为什么,还是谷歌找到答案:是因为64位系统的问题.解决方法是:重新定义一下Machine64(参考链接一). RegistryKey localMachine64 = RegistryKey.OpenBaseKey(RegistryHive.

【VS调试】C#读写Windows 7注册表时抛出“不允许所请求的注册表访问权”的解决办法

原文:[VS调试]C#读写Windows 7注册表时抛出"不允许所请求的注册表访问权"的解决办法 项目 - 属性 - 安全性,"使用ClickOnce",修改app.mainfest,再取消"使用ClickOnce" [另有一篇参考文章:http://blog.csdn.net/wonsoft/article/details/6598407]     在XP/2003下调试得好好的程序,到了windows7下,却抛出"不允许所请求的注册

对注册表进行编辑的三种途径_注册表

了解了关于注册表的基本内容之后,我们就可以正式进入我们所要讨论的话题了:对注册表进行编辑修改!一般来说,要想对注册表进行增.删.改,可以有以下三种途径: 第一种途径:直接修改(最不安全,但最直接最有效) 就是通过注册表编辑器直接的来修改注册表的键值数据项,这样做会避免在注册表中留下垃圾(虽然都很小,但越来越多会拖慢系统速度),但是要求用户有一定的注册表知识,熟悉注册表内部结构而且一定要小心谨慎. 注册表编辑器是一个可以让你改变系统注册设定的高级工具WIN98注册表编辑器的常用操作注册表编辑器是一

从注册表读取程序的版本

程序|注册表 从注册表读取程序的版本 屠恩海(SunHai) 开发工具:Microsoft Visual Studio .NET 2003 操作系统:Windows XP Registry 类简介 用Visual Studio .NET读写注册表一般用到Registry类. Registry类提供在运行 Windows 的计算机上的注册表中找到的标准根项集. 注册表是一个存储设备,包含有关应用程序.用户和默认系统设置的信息.例如,应用程序可以使用注册表来存储在应用程序关闭后需要保留的信息,并在应