【Qt】QSettings读写注册表、配置文件【转】
简述
一般情况下,我们在开发软件过程中,都会缓存一些信息到本地,可以使用轻量级数据库sqlite,也可以操作注册表、读写配置文件。
关于QSettings的使用前面已经介绍过了,比较详细,见“更多参考”,下面介绍下QSettings常用功能-读写注册表、配置文件。
优点
无需指定注册表路径
一般情况下,我们需要定义一个宏,或者常量字符串来指定保存的注册表位置。
#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,所以不会被删掉。
既然这样,那么我们的疑问也就不复存在了。
更多参考
原文作者:一去丶二三里
作者博客:去作者博客空间
【Qt】QSettings读写注册表、配置文件【转】的更多相关文章
- QSettings读写注册表、配置文件
简述 一般情况下,我们在开发软件过程中,都会缓存一些信息到本地,可以使用轻量级数据库sqlite,也可以操作注册表.读写配置文件. 关于QSettings的使用前面已经介绍过了,比较详细,见" ...
- QT QSettings读写配置文件
QT QSettings读写配置文件 需要用一个配置文件来保存程序的初始值,同时也需要做保存修改后的值. 那么借助于QSetting 就可以达到目的. 注意,生成的是 ini 文件! //1.创建和读 ...
- javascript取得机器名,用户名,读写注册表,启动应用程序
javascript取得机器名,用户名,读写注册表,启动应用程序//javascript有个特殊的对象ActiveXObject,通过它可以访问windows的本地文件系统和应用程序,比如:有的时候我 ...
- c#读写注册表示例分享
c#读写注册表示例,示例中有详细注释. 代码: //写注册表RegistryKey regWrite;//往HKEY_CURRENT_USER主键里的Software子键下写一个名为“Test”的子键 ...
- nim读写注册表的小例子
nim读写注册表的小例子 2018年5月7日 15:11:58 codegay 贴一个nim读写注册表的例子,虽然简单,但是nim官方没有写windows注册表相关的文档, 我贴的例子兴许能帮大家省点 ...
- 倍福TwinCAT(贝福Beckhoff)基础教程5.1 TwinCAT-3 读写注册表
读写注册表和读写文件一样,里面涉及的输入类型比较复杂,需要参考官方范例 sSubKey是指注册表的路径 sValName是指注册表要写入的名值对的名称 eValType是一个枚举类型(而且不是什么常规 ...
- QT之setting注册表项
1.头文件 #include <QSettings> 2.read注册表项 void MainWindow::readSettings() // 读取窗口设置 { QSettings se ...
- 【转载】 C#读写注册表
文章地址:https://blog.csdn.net/younghaiqing/article/details/61918968 自Windows95以来的所有Windows版本中,注册表是包含Win ...
- vc读写注册表
注册表是Windows重要组成部分,注册表记录了大量有关电脑软硬件的信息.注册表中的值通过其名称标识.值名称由与键名相同的字符组成.值本身可以是字符串.二进制数据或者是32位无符号值.在这里我们主要运 ...
随机推荐
- Handler发送消息
Handler发送消息小结 字数283 阅读210 评论0 喜欢1 obtainMessage()得到一个Message对象. 创建一个Message然后发送是这么写的: Message msg = ...
- 亚马逊副总裁谈Marketplace平台的个性化服务
说到个性化,亚马逊无疑是挖掘与利用数据为消费者打造个性化网购体验的先驱之一.而现在,几乎所有的公司和网站都在利用更加个性化的推荐算法为用户提供更好的购物和浏览体验. 亚马逊近年来尤其重视将其个性化特性 ...
- Access to the path '' is denied.解决方案
在本地测试正常,但一上传到服务器上的时候,那个就提示Access to the path ‘路径’ is denied.我在网上找了很多资料,最后终于解决了,原来是因为在该文件的上级文件夹没有修改权限 ...
- Java 多线程-上课总结
Java 多线程 一.操作系统中线程和进程的概念 现在的操作系统是多任务操作系统.多线程是实现多任务的一种方式. 进程是指一个内存中运行的应用程序,每个进程都有自己独立的一块内存空间,一个进程中可以启 ...
- HTML超出文本显示省略号...[text-overflow]
需要对div或者span同时应用Css: text-overflow:ellipsis; white-space:nowrap; overflow:hidden; 即可实现所想要得到的溢出文本显示省略 ...
- JAVA中的deflate压缩实现
在文件的传输过程中,为了使大文件能够更加方便快速的传输,一般采用压缩的办法来对文件压缩后再传输,JAVA中的java.util.zip包中的Deflater和Inflater类为使用者提供了DEFLA ...
- 浅析console和浏览器命令行API
一.console对象: F12或者Control+Shift+i(Win)/ Alt+Command+i(Mac)打开浏览器自带的开发工具,选择顶部tab中的最后一项console,这样你就可以尽情 ...
- Bootstrap,导航栏点击效果修复(补)
前言: 昨天晚上休息,忘记发博客了.对于学习这件是,还是需要坚持的.想想自建一个Jekyll博客模版还是很兴奋的,话不多说,看正文吧! 关于开发: 先看个Demo吧,点这里.你会发现,点击是没有效果 ...
- SQL Server 2008安装失败问题以及解决办法
一.检测过程中重启失败解决办法 在键盘上按下组合键[Win]+[R],调出运行窗口. 在窗口中输入“regedit”,点击确定,打开注册表管理界面. 在注册表左侧目录栏中找到如下位置:“HKEY_LO ...
- JsonHelper类(序列化和反序列化辅助类)
1: using System; 2: using System.Collections.Generic; 3: using System.Linq; 4: using System.Web; ...