会话管理¶
如何使用Qt进行会话管理。
一个会话是一组正在运行的应用程序,每个应用程序都有特定的状态。会话由一个称为会话管理器的服务控制。参与会话的应用程序称为会话客户端。
会话管理器代表用户向其客户端发出命令。这些命令可能会导致客户端提交未保存的更改(例如通过保存打开的文件),为将来的会话保留其状态,或优雅地终止。这些操作的集合称为会话 管理。
在通常情况下,会话包括用户在其桌面上同时运行的所有应用程序。然而,在Unix/X11下,会话可能包括在不同计算机上运行的应用程序,并且可能跨越多个显示器。
关闭会话¶
会话由会话管理器关闭,通常是在用户想要注销时代表用户执行。系统在紧急情况下也可能执行自动关闭,例如,如果即将断电。显然,这些类型的关闭之间存在显著差异。在第一种情况下,用户可能希望与应用程序交互,明确指定哪些文件应保存,哪些应丢弃。在后一种情况下,没有时间进行交互。甚至可能没有用户坐在机器前!
不同平台上的协议和支持¶
在macOS和Windows 2000之前的Microsoft Windows版本中,应用程序还没有像完整的会话管理这样的功能,即无法恢复之前的会话。(Windows 2000和XP提供了“休眠”功能,其中整个内存被保存到磁盘并在机器重新启动时恢复。)它们确实支持优雅的注销,应用程序有机会在获得用户确认后取消该过程。这是与QGuiApplication::commitDataRequest()信号相对应的功能。
X11 自 X11R6 以来已支持完整的会话管理。
使会话管理与Qt一起工作¶
首先,将一个槽连接到QGuiApplication::commitDataRequest()信号,以使您的应用程序能够参与优雅的注销过程。如果您仅针对Microsoft Windows平台,这是您可以且必须提供的全部内容。理想情况下,您的应用程序应提供一个类似于以下内容的关闭对话框:
此对话框的示例代码可以在 QSessionManager::allowsInteraction() 的文档中找到。
为了完整的会话管理(目前仅在X11R6上支持),您还必须注意保存应用程序的状态,并可能在会话的下一个生命周期中恢复状态。这种保存是通过实现一个连接到QGuiApplication::saveStateRequest()信号的槽来完成的。您在此函数中保存的所有状态数据都应使用会话标识符QGuiApplication::sessionId()进行标记。此应用程序特定的标识符是全局唯一的,因此不会发生冲突。(有关保存/恢复特定Qt应用程序状态的信息,请参见QSessionManager。)
恢复通常在应用程序的 main() 函数中进行。检查 QGuiApplication::isSessionRestored() 是否为 true。如果是这种情况,再次使用会话标识符 QGuiApplication::sessionId() 来访问您的状态数据并恢复应用程序的状态。
重要提示: 为了让窗口管理器能够恢复窗口属性,如堆叠顺序或几何信息,您必须使用唯一的应用程序范围内的对象名称来标识您的顶层小部件(参见 QObject::setObjectName())。在恢复应用程序时,您必须确保所有恢复的顶层小部件都被赋予与之前相同的唯一名称。
测试和调试会话管理¶
由于操作系统本身缺乏此功能,macOS和Windows上的会话管理支持相当有限。只需关闭会话并验证您的应用程序是否按预期运行。在启动您的应用程序之前,启动另一个应用程序(通常是集成开发环境)可能是有用的。这个其他应用程序随后会收到关闭消息,从而允许您取消关闭。否则,您将不得不在每次测试运行后重新登录,这本身不是问题,但很耗时。
在Unix上,您可以使用支持标准X11R6会话管理的桌面环境,或者,推荐的方法是使用X联盟提供的会话管理器参考实现。这个示例管理器称为xsm,并且是标准X11R6安装的一部分。与X11一样,提供了一个有用且信息丰富的手册页。使用xsm是直接的(除了基于Athena的笨拙用户界面)。这里有一个简单的方法:
运行 X11R6。
在你的主目录中创建一个包含单行的点文件
.xsmstartupxterm这告诉
xsm默认/故障安全会话只是一个 xterm,没有其他内容。否则xsm会尝试调用包括窗口管理器twm在内的许多客户端,这并不十分有用。现在从另一个终端窗口启动
xsm。会话管理器窗口和 xterm 都会出现。xterm 有一个很好的特性,使它与你当前运行的所有其他 shell 不同:在其 shell 中,SESSION_MANAGER环境变量指向你刚刚启动的会话管理器。从新的xterm窗口启动您的应用程序。它将自动连接到会话管理器。您可以使用ClientList按钮检查连接是否成功。
注意
在启动或结束会话管理的客户端时,切勿保持ClientList打开!否则
xsm可能会崩溃。使用会话管理器的检查点和关闭按钮,并尝试不同的设置,观察您的应用程序的行为。保存类型本地意味着客户端应保存其状态。它对应于QGuiApplication::saveStateRequest()信号。全局保存类型要求应用程序将其未保存的更改保存在永久、全局可访问的存储中。它会调用QGuiApplication::commitDataRequest()。
每当有东西崩溃时,责怪
xsm而不是Qt。xsm远未成为用户桌面上可用的会话管理器。然而,它足够稳定和有用,可以作为测试环境。