# Inkscape 自定义工具偏好设置存储与读取指南
在 Inkscape 开发中,为自定义工具(如 Select tool)添加并管理用户偏好设置,需遵循其特定的 XML 架构。该机制将默认值定义在源码中,而用户的实际配置存储在本地文件中。
## 偏好的存储位置
Inkscape 的偏好数据并非直接修改 `src/preferences-skeleton.h` 中的默认值,而是保存在用户本地的 XML 文件中。
- **Linux**: `~/.config/Inkscape/preferences.xml` (0.47 及以后版本)
- **Windows**: `%APPDATA%\inkscape\preferences.xml`
该文件层级结构类似 GConf 数据库或 Windows 注册表。元素节点对应文件夹,属性对应条目。例如,若要为 Select tool 添加移动距离选项,应在 `tools` 组下找到 `eventcontext id="select"` 元素,并将新值作为其属性(如 `bar="1.0"`)存储,而非创建新的嵌套元素。
## 默认值与源码的关系
`src/preferences-skeleton.h` 文件仅用于定义**默认值**。当用户首次运行或偏好文件缺失某项时,Inkscape 会依据此文件生成初始配置。一旦用户通过界面修改了设置,本地 XML 文件中的值将优先于源码中的默认值生效。
## 程序内的读取与写入
在代码中访问偏好值需包含 `#include "preferences.h"`,并调用静态函数获取单例对象:
```cpp
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
```
### 读取值
使用路径字符串(基于 `id` 属性)和类型转换方法读取。例如读取移动距离:
```cpp
double val = prefs->getDouble("/tools/select/bar", 1.0);
```
- **路径语法**:类似 XPath,但使用 `id` 而非元素名(如 `/tools/select/bar`)。
- **默认参数**:第二个参数为无值时的返回默认值。
- **时效性**:必须在每次使用前调用,因为用户可能通过对话框实时修改了设置。
### 写入值
若需将新值写回内存表示:
```cpp
prefs->setDouble("/tools/select/bar", new_bar);
```
Inkscape 会在退出时自动将更改保存至 XML 文件,且变更在崩溃后仍会被恢复(由崩溃处理器保护)。
## 监听变化:观察者机制
若偏好值与 UI 元素直接关联,建议避免重复读取,转而使用**观察者(Observer)**机制。
1. **定义观察者**:继承 `Inkscape::Preferences::Observer` 类。
2. **注册路径**:在构造函数中指定监控的路径(如 `"/tools/select/bar"`)。
3. **接收通知**:实现 `notify` 方法,当值更新时自动触发。
```cpp
class MyObserver: public Inkscape::Preferences::Observer {
public:
MyObserver() : Inkscape::Preferences::Observer("/tools/select/bar") {}
virtual void notify(Inkscape::Preferences::Entry const &value)
{
double new_value = value.getDouble();
// 更新 UI 或执行逻辑
}
};
```
注意:修改偏好值时需防止无限递归调用。
## 注意事项
- **类型安全**:使用 `getIntLimited`/`getDoubleLimited` 处理边界情况,布尔值应使用 `getBool`/`setBool`。
- **用户优先**:代码不应假设所有值均由程序写入,需兼容用户手动修改的情况。
- **未来变化**:该 XML 存储机制可能在未来被弃用,但目前仍是标准做法。