25年来,KDE社区一直在使用Qt开发各种自由软件产品。其中包括Plasma桌面环境,像Krita和Kdenlive这样的创意工具,像GCompris这样的教育应用程序,像Kontact这样的群件套件以及无数其他应用程序,实用程序和小部件。
Qt以其丰富的高质量跨平台API而闻名。但是,它并不涵盖每个用例。事实上,这是不可能的。因此,为了填补空白,随着时间的推移,KDE 创建了已合并到许多 KDE 项目中的代码。为了促进在 KDE 项目之外重用这些经过实战考验的解决方案,KDE以模块化库的形式共享这些代码。
我们称这些库为KDE框架。
目前,有 83 个 KDE 框架提供了广泛的功能。例如,KNotifications允许您在Windows,macOS,Linux和Android上创建弹出通知,而无需编写特定于平台的代码。其他框架为专门的库或接口提供包装器,使它们更容易被Qt程序员使用。例如,bluez-qt框架为bluez D-Bus API提供了一个Qt风格的接口。一些框架是有用的类的集合,如KWidgetsAddons,其中包含许多不属于QtWidgets的有用小部件。
作为Qt开发人员,您可能在不知情的情况下使用了使用KDE框架构建的软件。为 Kate 和 KDevelop 等 KDE 应用程序提供支持的语法高亮框架也用于 Qt Creator。
利用 KDE 框架有很多好处。在本系列中,我们将研究其中的一些,提供实用和真实世界的示例,帮助您学习如何将 KDE 框架整合到您自己的产品中。
在本系列的第一篇博客中,我想向您介绍KConfig。
KConfig是最常用的框架之一。它允许开发人员在文件系统中存储和获取配置数据。它的基本功能类似于Qt自己的QSettings,但它提供了一些附加功能。
在应用程序中使用 KConfig 之前,我们需要将其添加到我们的构建系统中。对于 CMake,这是按如下方式完成的:
如果您的应用程序使用 QMake,您只需要:
以下代码显示了 KConfig 的基本用法:
首先,创建一个 KConfig 对象。默认情况下,配置保存在QStandardPaths::GenericConfigLocation中具有指定名称的文件中,但是可以调整确切的位置。
配置条目按组进行组织。每个 KConfig 对象可以包含多个组,每个组包含多个包含配置数据的键值对。
要读取配置条目,请首先从 KConfig 对象创建 KConfigGroup,然后使用 readEntry 查询特定键。readEntry 采用可选的默认值,当不存储该键的数据时,将使用该值。
要编写设置,请使用 writeEntry。数据不会立即写入磁盘。当 KConfigGroup 对象被析构时,将执行所有挂起的写入操作。可以使用 sync() 方法强制写入磁盘。
到目前为止,所有这些都可以通过QSettings进行。那么,使用KConfig有什么好处呢?
QSettings和KConfig都允许配置级联。在这里,配置值是从两个位置读取的:系统范围的配置值和每用户的位置。这允许定义系统范围的默认值,并使用户能够覆盖它们的值。但是,在企业设置中,这可能是不可取的。KConfig允许系统管理员将设置标记为不可变,以防止用户覆盖提供的默认值。这不需要在应用程序中更改任何代码。应用程序可以查询某个键是否标记为不可变,以禁用相关的 UI 部分。
有时两个进程访问同一个配置文件。在这里,当另一个进程更改配置时通知一个进程,以便它可以做出相应的反应,这一点很重要。KConfigWatcher允许通知另一个进程有关配置更改的信息。它通过D-Bus做到这一点。因此,它仅适用于D-Bus可用的系统(即Linux)。
KConfig(和QSettings)的这种简单用法有许多缺点。库/编译器没有关于配置数据结构的信息。大多数访问都是使用字符串标识符完成的。这些容易出现键入错误,编译器无法在生成时验证这些错误。也没有关于配置条目的数据类型的信息,例如,条目是单个字符串、字符串列表还是整数。另一个问题是KConfig不能直接在QML上下文中使用。
KConfig提供了解决这两个问题的KConfigXT机制。它基于配置数据结构的 XML 描述。在编译时,此信息用于生成用于访问配置的C++类。该类还可以将条目公开为属性,以便 QML 可以直接使用它。
上面以 XML 描述表示的示例如下所示:
这存储在myappsettings.kcfg文件中。
KConfigXT 的行为由一个单独的配置文件 myappsettings.kcfgc 控制:
然后上面的代码示例变为: