我们有时会在 #gtk+ 中收到关于 GSettings 的问题,以及在“简单”情况下使用此 API 是否是个好主意。在我看来,答案非常明确,是肯定的,本文试图解释原因。
好处
GSettings 的一个优点是它是一个高级 API,具有适用于各种本机配置系统的后端。因此,如果你曾经将你的应用程序移植到 OS X 或 Windows,你的应用程序将自动使用预期的平台 API 来存储其设置(Windows 上的注册表和 OS X 上的 plist)。
即使你的应用程序永远不会移植到这些平台,Linux 上使用的 dconf 后端也具有强大的功能,例如配置文件和锁,这些功能使系统管理员可以配置你的应用程序,而无需你担心。
不幸的是,GSettings 的文档使其看起来比实际情况更复杂,因为它并没有真正试图隐藏可供你使用的强大功能(配置文件、供应商覆盖、翻译后的默认值、复杂类型、绑定等)。
因此,这里有一个关于 GSettings 的第一步的指南,在简单的情况下。
入门
让我们从最简单的设置开始:布尔值。
要克服的最大障碍是 GSettings 坚持使用模式,该模式定义每个键的数据类型和默认值。
<schemalist>
<schema path="/org/gnome/recipes/"
id="org.gnome.Recipes">
<key type="b" name="use-metric">
<default>true</default>
<summary>Prefer metric units</summary>
<description>
This key determines whether values
such as temperatures or weights will
be displayed in metric units.
</description>
</key>
</schema>
</schemalist>
模式需要安装(这样做的好处是 dconf-editor 等工具可以使用模式信息)。如果你正在使用 autotools,则使用宏支持此功能。只需添加
GLIB_GSETTINGS
到你的 configure.ac,和
gsettings_SCHEMAS = org.gnome.Recipes.gschema.xml
@GSETTINGS_RULES@
到 Makefile.am。使用 meson 的设置类似。
现在我们已经定义了我们的键,我们可以像这样获取它的值
s = g_settings_new ("org.gnome.Recipes");
if (g_settings_get_boolean (s, "use-metric"))
g_print ("Using metric units");
我们可以像这样设置它
s = g_settings_new ("org.gnome.Recipes");g_settings_set_boolean (s, "use-metric", TRUE);
为其他基本类型(如整数、浮点数、字符串等)使用 GSettings 非常相似。只需使用适当的 getter 和 setter。
你可能想知道我们在这里创建的设置对象。只要你需要它们,就可以创建它们。如果你愿意,也可以创建一个全局单例,但除非你想监视设置的更改,否则没有真正需要这样做。
下一步:复杂类型
除了基本类型之外,你还可以使用 GVariant 类型系统的全部功能来存储复杂类型。例如,如果你需要存储关于平面中一个圆的信息,你可以将其存储为类型为 * (ddd) * 的三元组,存储圆心的 x、y 坐标和半径。
要处理代码中具有复杂类型的设置,请使用 g_settings_get() 和 g_settings_set(),它们以 GVariant 的形式返回和接受值。
下一步:可重定位的模式
如果你的应用程序使用帐户,你可能需要查看可重定位的模式。可重定位的模式是你需要单独存储同一配置的多个实例时所需要的。这方面的一个典型例子是帐户:你的应用程序允许创建多个帐户,并且每个帐户都具有与之相关的相同类型的配置信息。
GSettings 通过省略模式中的路径来处理此问题
<schemalist>
<schema id="org.gnome.Recipes.User">
<key type="b" name="use-metric">
<default>true</default>
</key>
</schema>
</schemalist>
相反,我们需要在创建 GSettings 对象时指定路径
s = g_settings_new_with_path ("org.gnome.Recipes.User",
"/org/gnome/Recipes/Account/mclasen");
if (g_settings_get_boolean (s, "use-metric"))
g_print ("User mclasen is using metric units");
你需要自己设计一个模式,将你的帐户映射到唯一的路径。
绊脚石
使用 GSettings 时需要注意一些事项。其中之一是 GLib 需要能够在运行时找到已编译的模式。在不安装的情况下从构建目录运行应用程序时,这可能是一个问题。要处理这种情况,你可以设置 GSETTINGS_SCHEMA_DIR 环境变量,以告知 GLib 在哪里可以找到已编译的模式
GSETTINGS_SCHEMA_DIR=build/data ./build/src/gnome-recipes
另一个绊脚石是 GSettings 以序列化 GVariant 的形式读取 XML 中的默认值。对于常见的字符串情况,这可能会有点令人惊讶,因为它意味着我们需要在字符串周围加上引号
<default>'celsius'</default>
但是这些都是小问题,一旦你了解了它们,就可以轻松避免它们。