短目录简介QSettings创建存储格式存储位置跨平台注意事项存储格式自定义演示
前言
以前用Android开发时,有时也会根据用户的喜好进行保存,但当时使用的是SharedPreferences。
数据最终保存为xml文件,并保存密钥-值对。 Qt也有类似的类。 是QSettings。
QSettings是Qt文档 - QSettings
根据文档,QSettings在平台无关类以前、Qt - 跨平台程序打包发布中提到了Qt跨平台的实现。 不知道这个概念的伙伴可以去看。
//最简单,nativeformatqsettingssettings (' my soft ',' Star Runner ' ); //ini文件qsettingssettings (/home/Petra/misc/myapp.ini )、qsettings : ini格式); //plist文件qsettingssettings (/users/Petra/misc/myapp.plist ),qsettings :3360本机格式); 可以在堆栈或堆中创建QSettings对象。 也可以使用new创建。 QSettings对象的构建和销毁非常快。
保存格式保存在QSettings中的文件格式如下。
NativeFormat
使用最适合平台的存储格式保存设置。
在Windows上,是指系统注册表。
在macOS和iOS中,这意味着cf首选项API。
Unix上,即INI格式的文本配置文件。
Registry32Format
仅限Windows :显式访问32位系统注册表。
在32位Windows或64位Windows上的32位APP应用程序的工作方式与指定的本机格式相同。
Registry64Format
仅限Windows :显式访问64位系统注册表。
此操作与在32位Windows或64位windows 64位APP应用程序中指定的本机格式相同。
IniFormat
将设置保存到INI文件。
注意:从INI文件读取设置时 不会保留类型信息。所有值将作为 QString 返回。
InvalidFormat
自定义类型; registerFormat ()返回的特殊值。
小结:用户设置信息。 Windows通常存储在系统注册表中,Macintosh和iOS则存储在属性列表文件. q列表中。 在Unix系统上,许多APP应用程序(包括kde APP应用程序)使用INI文本文件,而没有标准。
QSettings的API基于QVariant(可戳),可以使用大多数类型,如QString、QRect和QImage。
QSettings存储文件由指定设置的名称(键)的QString和QVariant组成,QVariant存储指定3358www.Sina.com/。 保存时只需调用setValue (。
保存保存有与键相关的数据
setValue()
为了避免可移植性问题,Qt团队建议遵守以下规则:
始终使用相同的大小写引用相同的键。
请勿使用相同的键名。 不区分大小写。
请不要在关键名称中使用正斜线((/)和() ) ) )。 反斜杠字符用于分隔子键。 在Windows上,QSettings将“”转换为“/”,使其相同。
与Unix文件路径一样,可以使用“/”字符作为分隔符来形成层次密钥
settings.setvalue ((主窗口/尺寸),双赢); () ); 要保存或恢复许多具有相同前缀的设置,请在关于键名,Windows注册表和INI文件使用不区分大小写的键,而macOS和iOS上的CFPreferences API 使用区分大小写的键。beginGroup (中指定前缀,退出时调用endGroup )。
g>注意: 如果已经存在具有相同键的设置,则现有值将被新值覆盖。为了提高效率,更改由事件循环按固定间隔自动保存至永久存储,所以可能不会立即更新到永久存储中。 若想立刻更新,可调用sync()手动提交更改。读取使用的是 value()
当使用 value()找不到键值时,将返回一个空的QVariant;当然我们也可以在使用value()时传入第二个参数作为 默认值 。
void MainWindow::writeSettings(){ QSettings settings("MySoft", "Star Runner"); settings.beginGroup("MainWindows"); settings.setValue("size",size()); settings.setValue("pos",pos()); settings.endGroup();}void MainWindow::readSettings(){QSettings settings("MySoft", "Star Runner"); settings.beginGroup("MainWindows"); //参数2:默认值 resize(settings.value("size",QSize(400,400)).toSize()); move(settings.value("pos",QPoint(200,200)).toPoint()); settings.endGroup();}要测试给定键是否存在,可调用 contains()。
注意:如果使用 beginGroup() 设置了一个组,则将键视为相对于该组的键。
要删除与键关联的设置,可调用 remove()。
QSettings settings;settings.setValue("ape");settings.setValue("monkey", 1);settings.setValue("monkey/sea", 2);settings.setValue("monkey/doe", 4);settings.remove("monkey");QStringList keys = settings.allKeys();// keys: ["ape"]如果在组中使用,且 key 为空,则将删除该组所以键值对:
QSettings settings;settings.setValue("ape");settings.setValue("monkey", 1);settings.setValue("monkey/sea", 2);settings.setValue("monkey/doe", 4);settings.beginGroup("monkey");settings.remove("");settings.endGroup();QStringList keys = settings.allKeys();// keys: ["ape"]要获取所有键的列表,可调用 allKeys()。
要删除所有键,可调用 clear()。
删除与此QSettings对象关联的 主要位置 中的所有条目。
后备位置 的条目不会被删除。
存储位置QSettings 有一个 备用机制,每次查找键值对的时候它会按顺序查找以下四个位置:
User, ApplicationUser, OrganizationSystem, ApplicationSystem, Organization这四个位置是Qt的抽象,使我们无须指定文件路径或注册表路径。
前面说到,claer() 只会删除主位置的所以条目,备用位置不受影响。
若想关闭该机制可调用 setFallbacksEnabled(false)。
接下来看一个例子:
QSettings obj1(("MySoft", "Star Runner"); QSettings obj2(("MySoft"); QSettings obj3((QSettings::SystemScope, "MySoft", "Star Runner"); QSettings obj4((QSettings::SystemScope, "MySoft");下表列举了以上QSettings的主要位置及备用位置:
注意:主要位置可用于读写,而后备位置仅作为读取时的备胎。
那么这些位置具体指哪里呢?
由于比较琐屑,可自行移步 QSettings平台特定说明
跨平台注意事项Windows系统注册表具有以下限制:子项不能超过255个字符,条目的值不能超过16,383个字符,并且键的所有值都不能超过65535个字符。 要解决这些限制的一种方法是使用存储的设置 IniFormat 而不是 NativeFormat 。
在Windows上,当使用Windows系统注册表时,QSettings不会保留该值的原始类型。 因此,设置新值时,值的类型可能会更改。
在macOS和iOS上,allKeys()将针对适用于所有应用程序的全局设置返回一些额外的键。这些键可以使用value()读取,但不能更改,只能被显示。 调用 setFallbacksEnabled(false) 将隐藏这些全局设置。
在macOS和iOS上,QSettings使用的CFPreferences API需要Internet域名而不是组织名称。 为了提供统一的API,QSettings从组织名称中派生了一个假域名,该算法在公司名称后附加“ .com”,并用连字符替换空格和其他非法字符。如果要指定其他域名,可使用以下函数:
QCoreApplication::setOrganizationDomain()QCoreApplication::setOrganizationName()QCoreApplication::setApplicationName()QSettings settings;另一种解决方案是使用预处理器指令:
#ifdef Q_OS_MAC Q_OS_MAC QSettings settings(("grenoullelogique.fr", "Squash");#else QSettings settings(("Grenoulle Logique", "Squash");#endif在macOS上,访问权限问题 。
自定义存储格式
该函数用于注册自定义存储格式。成功后,返回一个特殊的Format值,然后我们可将其传递给QSettings构造函数。若创建失败,则返回 InvalidFormat。
readFunc 和 writeFunc 参数是指向读取和写入一组键/值对的功能。始终以二进制模式打开读取和写入功能的QIODevice参数。
caseSensitivity 参数指定是否键区分大小写,默认值区分大小写。
默认情况下,如果使用了与组织名称和应用程序名称有关的构造函数,则使用的文件系统位置与IniFormat相同。当然也可使用setPath()指定其他位置。
bool readXmlFile(QIODevice &device, QSettings::SettingsMap &map);bool writeXmlFile(QIODevice &device, const QSettings::SettingsMap &map);int main(int argc, char *argv[]){ const QSettings::Format XmlFormat = QSettings::registerFormat("xml", readXmlFile, writeXmlFile); QSettings settings(XmlFormat, QSettings::UserScope, "MySoft", "Star Runner");} Demo下面是一个程序退出前自动保存用户设置的demo:
//mainwindow.hnamespace Ui {class MainWindow;}class MainWindow : public QMainWindow{ Q_OBJECTpublic: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); void writeSettings(); void readSettings(); private: Ui::MainWindow *ui;protected: virtual void closeEvent(QCloseEvent* event)override;};//mainwindow.cppMainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow){ ui->setupUi(this); //下次程序进入时自动加载设置 - 主界面构造函数中读取 readSettings();}void MainWindow::writeSettings(){ QSettings settings("MySoft", "Star Runner"); settings.beginGroup("MainWindows"); settings.setValue("size",size()); settings.setValue("pos",pos()); settings.endGroup();}void MainWindow::readSettings(){ QSettings settings("MySoft", "Star Runner"); settings.beginGroup("MainWindows"); //参数2:默认值 resize(settings.value("size",QSize(400,400)).toSize()); move(settings.value("pos",QPoint(200,200)).toPoint()); settings.endGroup();}//实现程序退出前保存用户设置 - 重写closeEvent()void MainWindow::closeEvent(QCloseEvent *event){ writeSettings();}