GSettings 初步

我们有时会在 #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 初步”的 2 条评论

  1. 编译后的模式文件是否与架构无关? 二进制格式在版本之间是否稳定?

    我问这个问题是因为我正在开发一个使用 GSettings 的 Python 应用程序,并且我正在尝试弄清楚如何打包(例如,我能让 pip 安装 gtimelog 工作吗?)。

  2. 该格式与用于存储 dconf 数据库的格式相同:gvdb。 所以是的,它是稳定的。 从某种意义上说,它是与架构无关的,无论它是在哪个架构上编写的,我们都可以读取它。 但它是用原生字节序编写的。

评论已关闭。