GSettings类提供了一个方便的API来存储和检索应用程序设置。
读写可以被认为是非阻塞的。使用GSettings读取设置通常是非常快的:在大致相同的数量级上(但比)GHashTable查找要慢。写入设置在返回应用程序的时间方面也非常快,但对于其他线程和其他进程来说可能非常昂贵。许多设置后端(包括dconf)具有延迟初始化,这意味着在通常情况下,用户使用他们的计算机而不修改任何设置,可以避免许多工作。对于dconf,在这种情况下甚至不需要启动D-Bus服务。因此,你应该只在用户显式操作时修改GSettings键。应该特别注意确保在启动期间不进行修改——例如,在设置preferences小部件的初始值时。内置的g_settings_bind()函数小心地不写入设置来响应它对小部件所做的修改所发出的通知信号。
当创建一个GSettings实例时,您必须指定一个模式来描述您的设置中的键及其类型和默认值,以及一些其他信息。
通常,模式有一个固定的路径,确定设置存储在概念上的全局设置树中的位置。然而,模式也可以是[relocatable][gsettings-relocatable]
,即不配备固定路径。例如,当模式描述了一个account
,并且你想要能够存储任意数量的账户时,这很有用。
路径必须以正斜杠(' / ')开始和结束
,并且不能包含两个连续的斜杠字符。路径应该根据与该设置所属的程序或库相关联的域名来选择。路径的例子有/org/gtk/settings/file-chooser/和/ca/desrt/dconf-editor/。路径不应该像GConf中那样以“/apps/”、“/desktop/”或“/system/”开头。
与其他配置系统(如GConf)不同,GSettings并不将键限制为字符串和数字等基本类型。GSettings将值存储为GVariant,并允许键为任何GVariantType。键名被限制为小写字符、数字和’ - '。此外,名称必须以小写字母开头,不能以“-”结尾,不能包含连续的连字符。
与GConf类似,GSettings模式中的默认值可以本地化,但本地化的值存储在gettext目录中,并通过在or元素的gettext-domain
属性中指定的域和在元素的l10n
属性中指定的类别进行查找。被翻译的字符串包含元素中的所有文本,包括周围的引号。
l10n
属性必须设置为消息或时间,并设置翻译的区域设置类别。默认情况下应该使用消息类别;将time用于可翻译的日期或时间格式。翻译注释可以作为XML注释直接添加到元素之上——建议添加这些注释以帮助翻译人员理解默认值的含义和含义。可以在元素上设置可选的翻译上下文属性,以消除使用相同字符串的多个默认值的歧义。
例如:
<!-- Translators: A list of words which are not allowed to be typed, in
GVariant serialization syntax.
See: https://developer.gnome.org/glib/stable/gvariant-text.html -->
<default l10n='messages' context='Banned words'>['bad', 'words']</default>
默认值的转换必须保持语法上有效的序列化GVariants(例如保留任何引号),否则将发生运行时错误。
GSettings以紧凑的二进制形式使用模式,该模式由[glib-compile-schemas]``[glib-compile-schemas]
实用程序创建。输入是XML格式的模式描述。
gschema XML格式的DTD可以在这里找到:gschema.dtd
[glib-compile-schemas]
工具希望模式文件具有扩展名.gschema.xml。
在运行时,模式由它们的id标识(在元素的id属性中指定)。模式id的约定是使用一个虚线名称,风格类似于D-Bus总线名称,例如“org.gnome.SessionManager”。特别是,如果设置是针对拥有D-Bus总线名称的特定服务,则D-Bus总线名称和模式id应该匹配。对于处理与指定应用程序无关的设置的模式,id不应该使用StudlyCaps,例如“org.gnome.font-rendering”。
除了GVariant类型,键还可以具有枚举类型。它们可以由或元素描述,如[示例][schema-]中所示。这种键的基本类型是string,但你可以使用g_settings_get_enum()、g_settings_set_enum()、g_settings_get_flags()、g_settings_set_flags()访问enum和flags键的字符串值对应的数值。
使用默认值的例子:
<schemalist>
<schema id="org.gtk.Test" path="/org/gtk/Test/" gettext-domain="test">
<key name="greeting" type="s">
<default l10n="messages">"Hello, earthlings"</default>
<summary>A greeting</summary>
<description>
Greeting of the invading martians
</description>
</key>
<key name="box" type="(ii)">
<default>(20,30)</default>
</key>
<key name="empty-string" type="s">
<default>""</default>
<summary>Empty strings have to be provided in GVariant form</summary>
</key>
</schema>
</schemalist>
枚举类型的例子:
<schemalist>
<enum id="org.gtk.Test.myenum">
<value nick="first" value="1"/>
<value nick="second" value="2"/>
</enum>
<flags id="org.gtk.Test.myflags">
<value nick="flag1" value="1"/>
<value nick="flag2" value="2"/>
<value nick="flag3" value="4"/>
</flags>
<schema id="org.gtk.Test">
<key name="key-with-range" type="i">
<range min="1" max="100"/>
<default>10</default>
</key>
<key name="key-with-choices" type="s">
<choices>
<choice value='Elisabeth'/>
<choice value='Annabeth'/>
<choice value='Joe'/>
</choices>
<aliases>
<alias value='Anna' target='Annabeth'/>
<alias value='Beth' target='Elisabeth'/>
</aliases>
<default>'Joe'</default>
</key>
<key name='enumerated-key' enum='org.gtk.Test.myenum'>
<default>'first'</default>
</key>
<key name='flags-key' flags='org.gtk.Test.myflags'>
<default>["flag1","flag2"]</default>
</key>
</schema>
</schemalist>
默认值在应用程序安装的模式中定义。有时候,供应商或分发者需要调整这些默认值。由于为模式的XML源代码打补丁是不方便且容易出错的,所以[glib-compile-schemas][glib-compile-schemas]读取所谓的vendor override `文件。这些是与XML模式源位于同一目录下的keyfile,可以覆盖默认值。模式id作为密钥文件中的组名,其值应该是序列化的GVariant形式,如下面的例子所示:
[org.gtk.Example]
key1='string'
key2=1.5
glib-compile-schemas要求模式文件具有扩展名.gschema.override
GSettings的一个非常方便的特性允许您使用g_settings_bind()将GObject属性直接绑定到设置。一旦GObject属性绑定到设置上,两边的更改就会自动传播到另一边。GSettings处理GObject和GVariant类型之间的映射等细节,并防止无限循环。
这使得将首选项对话框连接到底层设置非常容易。为了更方便,GSettings查找名为sensitivity的布尔属性,并自动将其绑定到绑定设置的可写性上。如果这个“magic”碍事,可以用G_SETTINGS_BIND_NO_SENSITIVITY标志抑制它。
可重定位模式是指在其元素上没有指定path属性的模式。通过使用g_settings_new_with_path(),可以为可重定位模式实例化一个GSettings对象,为实例分配一个路径。传递给g_settings_new_with_path()的路径通常由常量前缀加上某种形式的实例标识符动态构建;但它们必须仍然是有效的GSettings路径。路径也可以是常量,并与源自依赖库的全局安装的模式一起使用。
例如,可重定位模式可用于存储应用程序中不同窗口的几何信息。如果模式ID是org.foo.MyApp。窗口,它可以实例化路径/org/foo/MyApp/main/、/org/foo/MyApp/document-1/、/org/foo/MyApp/document-2/等。如果任何路径是已知的,它们可以指定为父模式中的元素,例如:
<schema id="org.foo.MyApp" path="/org/foo/MyApp/">
<child name="main" schema="org.foo.MyApp.Window"/>
</schema>
在使用GSettings时,有几件事需要注意。一个是GLib需要能够在运行时找到已编译的模式。在没有安装应用程序的情况下,在构建目录外运行应用程序可能会出现问题。要处理这种情况,你可以设置GSETTINGS_SCHEMA_DIR环境变量来告诉GLib在哪里找到编译后的模式:
GSETTINGS_SCHEMA_DIR=build/data ./build/src/gnome-recipes