QSettings帮助文档翻译

时间:2022-03-14 03:12:06

细节描述

QSettings类提供平*立的应用设置持久化。

用户往往期待应用能记忆其设置(窗口大小、位置、选项……等等),下次会话中依然生效。这种信息常被保存在Windows的系统注册、macOS和iOS的特性表文件中。在Unix系统,没有标准,许多应用(包括KDE程序)使用INI文本文件。

QSettings是这些技术的抽象,可以用可移动的形式保存应用设置。它也支持制定的保存格式。

QSettings的API基于QVariant,允许不费劲地保存绝大多数基于值的类型,例如QString、QRect和QImage。

如果你只需要临时保存的数据结构,考虑使用QMap<QString,QVariant>代替。

基本用法

创建一个QSettings对象,你必须传入你的公司或组织以及你的应用名称。如,你的产品名为Star Runner,你的公司名为MySoft,则QSetting对象的创建如下:

 QSettings settings("MySoft", "Star Runner");
QSettings对象既可以在栈上也可以在堆上创建(如使用new)。构造和销毁一个QStrings对象是很快的。

如果你的应用多处使用QStrings,你可能想要通过如下的方法指定你的组织名和应用名:

QCoreApplication::setOrganizationName() 和 QCoreApplication::setApplicationName(), 然后使用默认的QSettings 构造函数:

QCoreApplication::setOrganizationName("MySoft");
QCoreApplication::setOrganizationDomain("mysoft.com");
QCoreApplication::setApplicationName("Star Runner");
...
QSettings settings;
(这里,我们也指定了组织的网站。在macOS和iOS上,网站设定会替代组织名,若没有设定,其会通过组织名得到一个假的网址……)

QSetting保存设置。每个设置包括一个QString,用于指定设置的名字(键)和一个QVariant用于储存键相关的数据。写入一个设置,使用setValue()。如下:

settings.setValue("editor/wrapMargin", 68);
如果已经存在一项相同键的设置,则新的值会覆盖旧的。为了效率,设置的改动并不会立刻被保存稳固的存储中。(你总是可以调用sync()提交你的改动。)

你可以使用value()获取设置的值:

int margin = settings.value("editor/wrapMargin").toInt();
如果没有指定的名称的设置,将会返回一个空的QVariant(可以被转换为整型0)。你可以通过给value()传入第二个参数,来指定默认值:

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

QVariant and GUI Types
由于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支持的类型,相反的转换(如,从QColor到QVariant)是自动的,包括GUI相关的类型。

QSettings settings("MySoft", "Star Runner");
QColor color = palette().background().color();
settings.setValue("DataPump/bgcolor", color);
对于用户定制的类型,使用 qRegisterMetaType() 和 qRegisterMetaTypeStreamOperators() 注册后,可以被QSettings保存。
部分(Section)和键(Key)的语法
设置的键可以包含任何Unicode字符。WIndows注册表和INI文件使用大小写非敏感键,而macOS和iOS的CFPreference API使用大小写敏感键。为了避免可移植问题,有以下规则:

  1. 使用相同的大小写总是引用相同的键。如:如果在一处使用了“text fonts”作为键,则不能在任何地方将其引用为“Text Fonts”。
  2. 避免键名除了大小写外完全相同。如“MainWindow”和“mainwindow”。
  3. 在部分名和键名上,不要用斜杠('/'和'\');反斜杠字符用于分开子键(见下文)。在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() 。
Fallback机制

(省略部分内容)

如果你想在所有平台上使用INI文件而不是本地的API,你可以传递QSettings::IniFormat作为QSettings构造器的第一个参数,然后传入作用范围(scope),组织名和应用名:

QSettings settings(QSettings::IniFormat, QSettings::UserScope, "MySoft", "Star Runner");
Settings Editor的例子让你体验不同的设置location和fallback机制开关的不同。
保存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();
}
参考 Window Geometry来讨论为什么在恢复窗口的几何形状时,调用 QWidget::resize() 和 QWidget::move() 比 QWidget::setGeometry() 更好。
readSettings()writeSettings()方法必须分别在主窗口的构造器和关闭事件中调用:

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

void MainWindow::closeEvent(QCloseEvent *event)
{
if (userReallyWantsToQuit()) {
writeSettings();
event->accept();
} else {
event->ignore();
}
}
参考 Application例子,这是自带的使用 QSettings的例子。
多线程或并发访问设置

  • A thread-safe function can be called simultaneously from multiple threads, even when the invocations use shared data, because all references to the shared data are serialized.
  • A reentrant function can also be called simultaneously from multiple threads, but only if each invocation uses its own data.

以上是thread-safe和reentrant的概念。

QSettings is reentrant. 这意味着可以同时在不同线程中使用QSetting对象。……。如果设置通过一个QSettings对象发生变化,这个变化会立刻对其他在同个进程同location的QSettings对象可见。
QSettings可以安全地在不同进程读和写,这可以使你能同时运行程序或将设置同时导入到不同的程序中。(后面略)