QSettings 类【官翻】

文章目录

  • 详述
    • 基本用法
    • QVariant和GUI类型
    • Section 和 Key 的语法
    • 后备机制
    • 恢复GUI应用程序的状态
    • 同时从多个线程或进程访问设置
    • 特定于平台的说明
      • 应用程序设置的存储位置
      • 直接访问INI和.plist文件
      • 直接访问Windows注册表
      • 在Windows上访问通用注册表设置
      • 平台限制
  • 公共类型
  • 公共函数
  • 静态公共函数
  • 重新实现的受保护的函数

QSettings 类

QSettings类提供与平台无关的持久性应用程序设置。

Header: #include < QSettings >
qmake: QT += core
Since:
Inherits: QObject
Inherited By:

详述

用户通常希望应用程序在会话中记住它的设置(窗口大小和位置、选项等)。这些信息通常存储在Windows的系统注册表中,macOS和iOS的属性列表文件中。在Unix系统上,由于缺乏标准,许多应用程序(包括KDE应用程序)都使用INI文本文件。

QSettings是围绕这些技术的抽象,使您能够以可移植的方式保存和恢复应用程序设置。 它还支持自定义存储格式。

QSettings的API基于QVariant,使您可以省力地保存大多数基于值的类型,例如QString,QRect和QImage。

如果您需要的只是一个基于非持久性内存的结构,请考虑改用QMap

基本用法

在创建QSettings对象时,必须传递公司或组织的名称以及应用程序的名称。例如,如果您的产品名为Star Runner,您的公司名为MySoft,您将构建QSettings对象如下:

 QSettings settings("MySoft", "Star Runner");

QSettings对象既可以在上创建,也可以在上创建(即使用new)。构造和销毁QSettings对象非常快。

如果您在应用程序的许多地方使用QSettings,您可能想要使用QCoreApplication::setOrganizationName()和QCoreApplication::setApplicationName()来指定组织名称和应用程序名称,然后使用默认的QSettings构造函数:

     QCoreApplication::setOrganizationName("MySoft");
     QCoreApplication::setOrganizationDomain("mysoft.com");
     QCoreApplication::setApplicationName("Star Runner");
     ...
     QSettings settings;

(在这里,我们还指定了该组织的互联网域。当设置Internet域名时,在macOS和iOS上使用它而不是组织名称,因为macOS和iOS应用程序通常使用Internet域名来标识自己。如果没有设置域名,则从该组织名称派生出一个假域名。有关详细信息,请参阅下面特定于平台的说明。)

QSettings存储设置。每个设置由一个指定设置名称()的QString和一个存储与键关联的数据的QVariant组成。要编写设置,使用setValue()。例如:

settings.setValue("editor/wrapMargin", 68);

如果已经存在具有相同键的设置,则现有值将被新值覆盖。为了提高效率,更改不能立即保存到永久存储中。(您总是可以调用sync()来提交您的更改。)

你可以使用value()返回设置的值:

int margin = settings.value("editor/wrapMargin").toInt();

如果没有指定名称的设置,QSettings将返回一个空的QVariant(可以转换为整数0)。

int margin = settings.value("editor/wrapMargin", 80).toInt();
  • 要测试给定的键是否存在,调用contains()。
  • 要移除与键相关联的设置,调用remove()。
  • 要获得所有键的列表,可以调用allKeys()。
  • 要删除所有键,调用clear()。

QVariant和GUI类型

因为QVariant是Qt核心模块的一部分,所以它不能提供对QColor、QImage和QPixmap等数据类型的转换功能,这些数据类型都是Qt GUI的一部分。换句话说,QVariant中没有toColor()、toImage()或toPixmap()函数。

相反,您可以使用QVariant::value()模板函数。例如:

 QSettings settings("MySoft", "Star Runner");
 QColor color = settings.value("DataPump/bgcolor").value<QColor>();

对于QVariant支持的所有数据类型,包括gui相关的类型,反向转换(例如,从QColor到QVariant)都是自动的:

 QSettings settings("MySoft", "Star Runner");
 QColor color = palette().background().color();
 settings.setValue("DataPump/bgcolor", color);

使用qRegisterMetaType()和qregistermetatypestreamoperator()注册的自定义类型可以使用QSettings存储。

Section 和 Key 的语法

设置键可以包含任何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还支持 “array” 概念。 有关详细信息,请参见beginReadArray() 和beginWriteArray() 。

后备机制

假设您已经创建了一个QSettings对象,组织名称为MySoft,应用程序名称为Star Runner。当你查找一个值时,最多可以按此顺序搜索四个位置:

  1. Star Runner应用程序的用户特定位置
  2. MySoft所有应用程序的用户特定位置
  3. Star Runner应用程序的系统范围的位置
  4. 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”表示该位置在读取时用作备用。

Locations obj1 obj2 obj3 obj4
1. User, Application X
2. User, Organization o X
3. System, Application o X
4. System, Organization o o o X

这种机制的优点在于,它可以在Qt支持的所有平台上运行,并且仍然为您提供了很大的灵活性,而无需您指定任何文件名或注册表路径。

如果要在所有平台上使用INI文件而不是本机API,则可以将QSettings::IniFormat作为第一个参数传递给QSettings构造函数,然后是范围,组织名称和应用程序名称:

QSettings settings(QSettings::IniFormat, QSettings::UserScope,"MySoft", "Star Runner");

请注意,从INI文件读取设置时不会保留类型信息。 所有值将作为QString返回。

Settings Editor example 允许您尝试不同的设置位置,并打开或关闭后背机制。

恢复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("pos", QPoint(200, 200)).toPoint());
     settings.endGroup();
 }

有关为什么最好调用QWidget :: resize() 和QWidget :: move() 而不是QWidget :: setGeometry() 来恢复窗口几何的讨论,请参见窗口几何。

必须从主窗口的构造函数和close事件处理程序中调用readSettings() 和writeSettings() 函数,如下所示:

 MainWindow::MainWindow()
 {
     ...
     readSettings();
 }

 void MainWindow::closeEvent(QCloseEvent *event)
 {
     if (userReallyWantsToQuit()) {
         writeSettings();
         event->accept();
     } else {
         event->ignore();
     }
 }

有关使用QSettings的独立示例,请参见 “Application Example ” 示例。

同时从多个线程或进程访问设置

QSettings是可重入的。这意味着您可以同时在不同的线程中使用不同的QSettings对象。即使QSettings对象引用磁盘上的相同文件(或系统注册表中的相同条目),也可以保证这一点。如果通过一个QSettings对象修改了设置,则该更改将立即在任何在同一位置运行且处于同一进程中的其他QSettings对象中可见。

只要满足某些条件,就可以从不同的进程(可以是同时运行的应用程序的不同实例,也可以是不同的应用程序)安全地使用QSettings来读写相同的系统位置。对于QSettings :: IniFormat,它使用咨询文件锁定和智能合并算法来确保数据完整性。工作的条件是可写配置文件必须是常规文件,并且必须位于当前用户可以在其中创建新的临时文件的目录中。如果不是这种情况,则必须使用setAtomicSyncRequired() 关闭安全装置。

注意,sync() 导入其他进程所做的更改( 除了从此QSettings写入更改之外 )。

特定于平台的说明

应用程序设置的存储位置

如“后备机制”部分所述,QSettings会将应用程序的设置存储在最多四个位置,具体取决于设置是用户特定的还是系统范围的,以及设置是特定于应用程序的还是组织范围的。 为简单起见,我们假设该组织称为MySoft,而该应用程序称为Star Runner。

在Unix系统上,如果文件格式为NativeFormat,则默认使用以下文件:

  • $ HOME / .config / MySoft / Star Runner.conf(用于嵌入式Linux的Qt:$ HOME / Settings / MySoft / Star Runner.conf)
  • $ HOME / .config / MySoft.conf(嵌入式Linux的Qt:​$HOME / Settings / MySoft.conf)
  • 对于$ XDG_CONFIG_DIRS中的每个目录< dir >:< dir> / MySoft / Star Runner.conf
  • 对于$ XDG_CONFIG_DIRS中的每个目录< dir>:< dir> /MySoft.conf

注意:如果未设置XDG_CONFIG_DIRS,则使用/ etc / xdg的默认值。

在macOS版本10.2和10.3上,默认情况下使用以下文件:

  1. $ HOME / Library / Preferences / com.MySoft.Star Runner.plist
  2. $ HOME / Library / Preferences / com.MySoft.plist
  3. /Library/Preferences/com.MySoft.Star Runner.plist
  4. /Library/Preferences/com.MySoft.plist

在Windows上,NativeFormat设置存储在以下注册表路径中:

  1. HKEY_CURRENT_USER\Software\MySoft \Star Runner
  2. HKEY_CURRENT_USER\Software\MySoft \OrganizationDefaults
  3. HKEY_LOCAL_MACHINE\Software\MySoft\Star Runner
  4. HKEY_LOCAL_MACHINE\Software\MySoft\OrganizationDefaults

注意:在Windows上,对于以WOW64模式运行的32位程序,设置存储在以下注册表路径中:
HKEY_LOCAL_MACHINE \ Software \ WOW6432node。

如果文件格式为NativeFormat,则在应用程序的主目录中为“ Settings / MySoft / Star Runner.conf”。

如果文件格式为IniFormat,则在Unix,macOS和iOS上使用以下文件:

  1. $ HOME / .config / MySoft / Star Runner.ini(用于嵌入式Linux的Qt:$ HOME / Settings / MySoft / Star Runner.ini)
  2. $ HOME / .config / MySoft.ini(用于嵌入式Linux的Qt:$ HOME / Settings / MySoft.ini)
  3. 对于​$ XDG_CONFIG_DIRS中的每个目录< dir>:< dir> / MySoft / Star Runner.ini
  4. 对于$ XDG_CONFIG_DIRS中的每个目录< dir>:< dir> /MySoft.ini

注意:如果未设置XDG_CONFIG_DIRS,则使用/ etc / xdg的默认值。

在Windows上,使用以下文件:

  1. FOLDERID_RoamingAppData \ MySoft \ Star Runner.ini
  2. FOLDERID_RoamingAppData \ MySoft.ini
  3. FOLDERID_ProgramData \ MySoft \ Star Runner.ini
  4. FOLDERID_ProgramData \ MySoft.ini

以FOLDERID_为前缀的标识符是特殊项目ID列表,将传递给Win32 API函数SHGetKnownFolderPath() 以获取相应的路径。

FOLDERID_ProgramData通常指向C:\ProgramData。

如果文件格式为IniFormat,则在应用程序的主目录中为“ Settings / MySoft / Star Runner.ini”。

配置文件.ini和.conf文件的路径可以使用setPath() 进行更改。 在Unix,macOS和iOS上,用户可以通过设置XDG_CONFIG_HOME环境变量来覆盖它们。 有关详细信息,请参见setPath() 。

直接访问INI和.plist文件

有时您确实想访问存储在特定文件或注册表路径中的设置。 在所有平台上,如果要直接读取INI文件,则可以使用QSettings构造函数,该构造函数以文件名作为第一个参数,并传递QSettings :: IniFormat作为第二个参数。 例如:

QSettings settings("/home/petra/misc/myapp.ini",QSettings::IniFormat);

然后,您可以使用QSettings对象读取和写入文件中的设置。

在macOS和iOS上,可以通过传递QSettings :: NativeFormat作为第二个参数来访问属性列表.plist文件。 例如:

QSettings settings("/Users/petra/misc/myapp.plist", QSettings::NativeFormat); 

直接访问Windows注册表

在Windows上,QSettings可让您访问系统注册表中用QSettings编写的设置(或受支持格式的设置,例如字符串数据)。 这是通过构造QSettings对象和注册表中的路径以及QSettings :: NativeFormat来完成的。

例如:

QSettings settings("HKEY_CURRENT_USER\\Software\\Microsoft\\Office",         QSettings::NativeFormat);

可以照常通过QSettings对象读取或写入出现在指定路径下的所有注册表项(使用正斜杠而不是反斜杠)。 例如:

settings.setValue("11.0/Outlook/Security/DontTrustInstalledFiles", 0);

请注意,如上所述,QSettings使用反斜杠字符来分隔子项。 如此一来,您将无法读取或写入包含斜杠或反斜杠的Windows注册表项。 如果需要,您应该使用本机Windows API。

在Windows上访问通用注册表设置

在Windows上,键可能同时具有值和子键。 通过使用“默认”或“”可以访问其默认值。 代替子项:

 settings.setValue("HKEY_CURRENT_USER\\MySoft\\Star Runner\\Galaxy", "Milkyway");
 settings.setValue("HKEY_CURRENT_USER\\MySoft\\Star Runner\\Galaxy\\Sun", "OurStar");
 settings.value("HKEY_CURRENT_USER\\MySoft\\Star Runner\\Galaxy\\Default"); // returns "Milkyway"

在Windows以外的其他平台上,“Default”和"."将被视为常规子项。

平台限制

虽然QSettings尝试理顺不同支持平台之间的差异,但在移植应用程序时仍应注意一些差异:

  • Windows系统注册表具有以下限制:子项不能超过255个字符,条目的值不能超过16,383个字符,并且键的所有值都不能超过65,535个字符。解决这些限制的一种方法是使用IniFormat而不是NativeFormat存储设置。

  • 在Windows上,当使用Windows系统注册表时,QSettings不会保留该值的原始类型。因此,设置新值时,值的类型可能会更改。例如,类型为REG_EXPAND_SZ的值将更改为REG_SZ。

  • 在macOS和iOS上,allKeys() 将为适用于所有应用程序的全局设置返回一些额外的键。可以使用value() 读取这些键,但不能更改它们,只能对其进行阴影处理。调用setFallbacksEnabled(false)将隐藏这些全局设置。

  • 在macOS和iOS上,QSettings使用的CFPreferences API需要Internet域名而不是组织名称。为了提供统一的API,QSettings会从组织名称中得出伪造的域名(除非组织名称已经是域名,例如OpenOffice.org)。该算法在公司名称后附加“ .com”,并用连字符替换空格和其他非法字符。如果要指定其他域名,请在main() 函数中调用QCoreApplication :: setOrganizationDomain() ,QCoreApplication :: setOrganizationName() 和QCoreApplication :: setApplicationName() ,然后使用默认的QSettings构造函数。另一种解决方案是使用预处理器指令,例如:

     #ifdef Q_OS_MAC
         QSettings settings("grenoullelogique.fr", "Squash");
     #else
         QSettings settings("Grenoulle Logique", "Squash");
     #endif
    
  • 在macOS上,不属于当前用户(即SystemScope)的访问设置的权限已随10.7(Lion)更改。 在该版本之前,具有管理员权限的用户可以访问这些权限。 对于10.7和10.8(Mountain Lion),只有root可以。 但是,10.9(Mavericks)再次更改了该规则,但仅适用于本机格式(plist文件)。

另请参见QVariant,QSessionManager,设置编辑器示例和应用程序示例。

公共类型

  1. enum Format
    QSettings使用的存储格式。
  2. typedef ReadFunc
  3. enum Scope
  4. typedef SettingsMap
  5. enum Status
  6. typedef WriteFunc

公共函数

  1. QSettings(QSettings::Scope scope, QObject *parent = nullptr)
  2. QSettings(QObject *parent = nullptr)
  3. QSettings(const QString &fileName, QSettings::Format format, QObject *parent = nullptr)
  4. QSettings(QSettings::Format format, QSettings::Scope scope, const QString &organization, const QString &application = QString(), QObject *parent = nullptr)
  5. QSettings(QSettings::Scope scope, const QString &organization, const QString &application = QString(), QObject *parent = nullptr)
  6. QSettings(const QString &organization, const QString &application = QString(), QObject *parent = nullptr)
  7. virtual ~QSettings()
  8. QStringList allKeys() const
  9. QString applicationName() const
  10. void beginGroup(const QString &prefix)
  11. int beginReadArray(const QString &prefix)
  12. void beginWriteArray(const QString &prefix, int size = -1)
  13. QStringList childGroups() const
  14. QStringList childKeys() const
  15. void clear()
  16. bool contains(const QString &key) const
  17. void endArray()
  18. void endGroup()
  19. bool fallbacksEnabled() const
  20. QString fileName() const
  21. QSettings::Format format() const
  22. QString group() const
  23. QTextCodec * iniCodec() const
  24. bool isAtomicSyncRequired() const
  25. bool isWritable() const
  26. QString organizationName() const
  27. void remove(const QString &key)
  28. QSettings::Scope scope() const
  29. void setArrayIndex(int i)
  30. void setAtomicSyncRequired(bool enable)
  31. void setFallbacksEnabled(bool b)
  32. void setIniCodec(QTextCodec *codec)
  33. void setIniCodec(const char *codecName)
  34. void setValue(const QString &key, const QVariant &value)
  35. QSettings::Status status() const
  36. void sync()
  37. QVariant value(const QString &key, const QVariant &defaultValue = QVariant()) const

静态公共函数

  1. QSettings::Format defaultFormat()
  2. QSettings::Format registerFormat(const QString &extension, QSettings::ReadFunc readFunc, QSettings::WriteFunc writeFunc, Qt::CaseSensitivity caseSensitivity = Qt::CaseSensitive)
  3. void setDefaultFormat(QSettings::Format format)
  4. void setPath(QSettings::Format format, QSettings::Scope scope, const QString &path)

重新实现的受保护的函数

  1. virtual bool event(QEvent *event) override

你可能感兴趣的:(#,Qt,文件目录,qt)