我们有时会在 #gtk+ 中收到关于 GSettings 的问题,以及在“简单”情况下使用此 API 是否是一个好主意。我的观点是,答案非常明确,是肯定的。这篇文章试图解释原因。
优点
GSettings 的一个优点是,它是一个高级 API,具有用于各种原生配置系统的后端。因此,如果您最终将您的应用程序移植到 OS X 或 Windows,您的应用程序将自动使用预期的平台 API 来存储其设置(Windows 上的注册表和 OS X 上的 plists)。
即使您的应用程序永远不会移植到这些平台,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>
但是这些都是小问题,一旦您了解了它们,就很容易避免。
编译后的模式文件是否与架构无关? 二进制格式在版本之间是否稳定?
我问这个问题是因为我正在开发一个使用 GSettings 的 Python 应用程序,并且我正在尝试弄清楚如何打包(例如,我能让 pip 安装 gtimelog 工作吗?)。
该格式与用于存储 dconf 数据库的格式相同:gvdb。 所以是的,它是稳定的。 从某种意义上说,它是与架构无关的,无论它是在哪个架构上编写的,我们都可以读取它。 但它是用原生字节序编写的。