25 QT之QSetting

25 QT之QSetting_第1张图片

简介

QSettings类提供了持久的跨平台应用程序设置。

用户通常期望应用程序记住它的设置(窗口大小、位置等)所有会话。这些信息通常存储在Windows系统注册表。在Unix系统中,在缺乏标准的情况下,许多应用程序(包括KDE应用程序)使用INI文本文件。

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

QSettings API基于QVariant,可以保存很多基础的类型,比如 QString、QRect、QImage等。

基本用法

当创建一个QSettings对象时,必须通过指定公司或组织名称以及产品名称,例如:公司名称为:MySoft,产品名为:Star Runner,那么可以用下列方式来构造QSettings对象:

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

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

如果你的应用程序在很多地方使用QSettings,则可以使用QCoreApplication::setOrganizationName() 和 QCoreApplication::setApplicationName()来指定组织名和应用名,然后使用默认的QSettings构造函数:

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

QSettings可以存储一系列设置。每个设置包括指定设置名称(键)的一个字符串和一个与该键关联的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();

如果之前没有配置过"editor/wrapMargin",则margin返回默认值80.

void QSettings::beginGroup(const QString & prefix);
void QSettings::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();

这将生成三个设置值:

  • mainwindow/size
  • mainwindow/fullScreen
  • outputpanel/visible
int QSettings::beginReadArray(const QString & prefix)

为当前组添加前缀,并开始从数组中读取。返回数组的大小。
例:

struct Login {
    QString userName;
    QString password;
};
QList logins;
...

QSettings settings;
int size = settings.beginReadArray("logins");
for (int i = 0; i < size; ++i) {
    settings.setArrayIndex(i);
    Login login;
    login.userName = settings.value("userName").toString();
    login.password = settings.value("password").toString();
    logins.append(login);
}
settings.endArray();
void QSettings::beginWriteArray(const QString & prefix, int size = -1)

为当前组添加前缀,并开始写大小为size的数组。如果大小为-1(默认值),系统会自动根据索引的数目确定。

如果有许多出现一定的键集,可以使用数组实现更容易。例如,假设想要保存的用户名和密码的长度可变的列表。然后,你可以写:

struct Login {
    QString userName;
    QString password;
};
QList logins;
...

QSettings settings;
settings.beginWriteArray("logins");
for (int i = 0; i < logins.size(); ++i) {
    settings.setArrayIndex(i);
    settings.setValue("userName", list.at(i).userName);
    settings.setValue("password", list.at(i).password);
}
settings.endArray();

生成的结果如下:

  • logins/size
  • logins/1/userName
  • logins/1/password
  • logins/2/userName
  • logins/2/password
  • logins/3/userName
  • logins/3/password
enum QSettings::Format

这个枚举类型指定QSettings所使用的存储格式。

  • QSettings::NativeFormat     0     使用平台最合适的存储格式设置。在Windows中,使用系统注册表;OS X和iOS中,使用的是CFPreferences API;在Unix中,使用的是INI格式的文本配置文件。
  • QSettings::IniFormat     1     存储在INI文件中的设置。
  • QSettings::InvalidFormat     16     registerFormat()返回的值

Unix中,NativeFor​​mat和IniFormat意思是一样的,只是文件扩展名不同(NativeFor​​mat为.conf,IniFormat 为.ini)。

enum QSettings::Scope

该枚举指定设置是否用户特定或同一系统的所有用户共享。

QSettings::UserScope 0 在一个位置存储特定于当前用户的设置(例如,用户的主目录)。
QSettings::SystemScope 1 在一个全局位置存储设置,以便在相同机器上所有用户访问同一组的设置。
void QSettings::setPath(Format format, Scope scope, const QString & path)

为给定格式和范围设置用来存储的路径。对于路径而言,该格式可以是自定义格式。

下表总结了默认值:

  • Windows                            IniFormat                     1.UserScope 2.SystemScope     1.%APPDATA% 2.%COMMON_APPDATA%
  • Unix                                   NativeFormat, IniFormat     1.UserScope 2.SystemScope     1.$HOME/.config 2./etc/xdg
  • Qt for Embedded Linux     NativeFormat, IniFormat     1.UserScope 2.SystemScope     1.$HOME/Settings 2./etc/xdg
  • OS X and iOS                   IniFormat                             1.UserScope 2.SystemScope     1.$HOME/.config 2./etc/xdg
     

在Windows、OS X、iOS中设置NativeFormat没有任何效果。

警告:此功能不会影响现有QSettings对象。

QVariant和GUI类型

因为QVariant是Qt Core模块的一部分,它不能提供转换功能到数据类型-例如:QColor、QImage、 QPixmap,因为这是Qt GUI的一部分。换句话说,QVariant中没有toColor()、toImage()、toPixmap()等接口。

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

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

逆转换(例如,从QColor到QVariant)是自动通过QVariant支持的所有数据类型,包括GUI相关类型:

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

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

存储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();
}

访问INI和.plist文件

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

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

然后,就可以对文件进行读写设置。
在OS X和iOS中,可以通过指定第二个参数为QSettings::NativeFormat访问属性列表的.plist文件。例如:

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


访问Windows注册表

在Windows中,QSettings可以在系统注册表访问由QSettings写入的设置(或设置支持的格式,如字符串数据)。通过使用一个注册表路径和QSettings::NativeFormat来构建一个QSettings对象。例如:

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

所有出现在指定的路径下的注册表条目,可以通过QSettings对象像往常一样进行读写(使用斜杠而不是反斜杠)。例如:

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

注意,反斜线字符,如前所述,使用QSettings分割为子项。这样一来,不能读写包含斜线或反斜线Windows注册表项,如果需要的话,应该使用Windows API。
 

你可能感兴趣的:(QT教程)