保存和加载窗口状态¶
用例¶
在会话之间保存和恢复窗口状态是某些应用程序的一个有用特性。
由于应用程序最了解它们的状态和几何形状——以及应用程序启动后是否应该应用这些状态和几何形状,以及如何应用——因此最好将此功能放在创建应用程序窗口的代码附近。
状态应该存储在哪里¶
有两种选择来存储窗口状态
位于
$XDG_CACHE_HOME/your.application.id(或在 Flatpak 应用程序内部运行时,简单地$XDG_CACHE_HOME) 的文件GSettings
两种选择都有其自身的优点和权衡。
第一种选择要求您编写序列化和反序列化代码,但它具有可移植性,并且不需要在运行时存在辅助文件,例如 GSettings 模式。这意味着您需要编写更多的代码,但它允许,例如,以未安装的方式运行您的应用程序。
第二种选择为您提供序列化和反序列化代码,但它要求您定义设置键模式并在已知位置安装它。这意味着您将使您的代码保持最小,但它也将需要安装。
通常情况下,在其他条件相同的情况下,最好使用 GSettings 而不是自定义文件。GSettings API 更好、更可靠、更快。
应该保存哪种状态?¶
通常应该保存的窗口状态很少
窗口大小
如果窗口支持,窗口是否最大化
如果窗口支持,窗口是否全屏
窗口位置最好交给窗口管理器。可以使用相同的方法保存其他状态,因此将它们作为练习留给读者。
提示
如果您的应用程序使用 GtkPaned 组件,您可能还想通过跟踪 GtkPaned:position 属性来保存手柄的位置。
窗口几何形状应该通过获取来自 GtkWindow:default-width 和 GtkWindow:default-height 属性的通知来更新;窗口状态,例如“最大化”和“全屏”,也映射到 GtkWindow 属性。
将状态保存和恢复到 GSettings¶
首先,您需要一个 GSettings 模式,以定义键、值的类型以及每个键的默认值
<schemalist>
<schema id="com.example.YourApp.State" path="/com/example/YourApp/State/">
<key name="width" type="i">
<default>640</default>
</key>
<key name="height" type="i">
<default>480</default>
</key>
<key name="is-maximized" type="b">
<default>false</default>
</key>
<key name="is-fullscreen" type="b">
<default>false</default>
</key>
</schema>
</schemalist>
一旦您有了模式,就可以将窗口属性映射到该模式定义的 GSettings 键
static void
my_application_window_init (MyApplicationWindow *self)
{
GSettings *settings = g_settings_new ("com.example.YourApp.State");
// update the settings when the properties change and vice versa
g_settings_bind (settings, "width",
self, "default-width",
G_SETTINGS_BIND_DEFAULT);
g_settings_bind (settings, "height",
self, "default-height",
G_SETTINGS_BIND_DEFAULT);
g_settings_bind (settings, "is-maximized",
self, "maximized",
G_SETTINGS_BIND_DEFAULT);
g_settings_bind (settings, "is-fullscreen",
self, "fullscreened",
G_SETTINGS_BIND_DEFAULT);
}
class MyApplicationWindow(Gtk.ApplicationWindow):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.settings = Gio.Settings(schema_id="com.example.YourApp.State")
self.settings.bind("width", self, "default-width",
Gio.SettingsBindFlags.DEFAULT)
self.settings.bind("height", self, "default-height",
Gio.SettingsBindFlags.DEFAULT)
self.settings.bind("is-maximized", self, "maximized",
Gio.SettingsBindFlags.DEFAULT)
self.settings.bind("is-fullscreen", self, "fullscreened",
Gio.SettingsBindFlags.DEFAULT)
My.ApplicationWindow : Gtk.ApplicationWindow {
public void init () {
var settings = new Settings ("com.example.YourApp.State");
// update the settings when the properties change and vice versa
settings.bind ("width", this,
"default-width", SettingsBindFlags.DEFAULT);
settings.bind ("height", this,
"default-height", SettingsBindFlags.DEFAULT);
settings.bind ("is-maximized", this,
"maximized", SettingsBindFlags.DEFAULT);
settings.bind ("is-fullscreen", this,
"fullscreened", SettingsBindFlags.DEFAULT);
}
}
const settings = new Gio.Settings({
schema: "com.example.YourApp.State",
});
const window = new Adw.ApplicationWindow({ application });
// update the settings when the properties change and vice versa
settings.bind(
"width",
window,
"default-width",
Gio.SettingsBindFlags.DEFAULT,
);
settings.bind(
"height",
window,
"default-height",
Gio.SettingsBindFlags.DEFAULT,
);
settings.bind(
"is-maximized",
window,
"maximized",
Gio.SettingsBindFlags.DEFAULT,
);
settings.bind(
"is-fullscreen",
window,
"fullscreened",
Gio.SettingsBindFlags.DEFAULT,
);
上面的代码将自动将属性设置为相应 GSettings 键中的值,并在属性发生更改时使用属性的值更新 GSettings 键。