2

在 Qt 的undo framework中,你可以拥有一堆QUndoCommand实例。这些中的每一个都描述了用户界面中的一个动作。在我们的应用程序中,我们有一组视图处理一组模型,其中一些是组合的,而且我们经常有多个视图处理同一组模型。我现在正在研究基于此框架撤消操作的能力。

现在,我熟悉使用命令类来描述 UI 操作的一般模式,但是这些应该表示 UI 元素中的状态更改,还是底层模型中的数据更改?一个命令类应该包含多少数据和状态?

一个例子来说明我的观点:假设您有一个QStandardItemModel作为基础模型,以及位于此之上的许多代理模型。每个代理模型都会进行排序转换,例如通过某个值的出现进行过滤。然后,如果我创建一个命令类来专门更改这些代理模型之一中的一个值,并且过滤条件发生更改,则该命令类的状态将变为无效。所以我还必须包含过滤器的状态,或者映射到最终的底层模型。另一种选择是为 UI 中的所有状态更改添加命令(例如,导致过滤条件更改的那些),但这样做的缺点似乎是要撤消的命令列表变得相当大。

这里有哪些最佳实践?

4

1 回答 1

2

这在一定程度上取决于您的应用程序及其使用方式,但以下是我过去用于撤消命令的一般准则:

  • 它是数据的一部分吗?如果是这样,用户应该能够撤消它。
  • 是否以某种方式保存(在应用程序会话之间记住)?如果是这样,用户应该能够撤消它。
  • 它与程序的主要目的有关吗?如果是这样,可以撤消。
  • 它是工作流程中经常完成的部分吗?如果是这样,可能无法撤消。
  • 它是基于其他变化而触发的吗?如果是这样,它应该在其他项目变回时撤消,而不是自行撤消。
  • 每次 *X* 发生时它都会重置吗?您可能能够摆脱它不在撤消堆栈中。
  • 是否可以通过相同的动作轻松撤消(例如,隐藏/显示额外信息)?您可能不希望它在撤消堆栈中。

基于此和您所写的内容,如果过滤是经常发生的事情和/或不能轻易更改回来,我可能会将撤消信息与模型(数据)和视图联系起来。如果过滤很简单(基本的子字符串过滤,比如搜索您的电子邮件主题行),那么它可能不需要成为撤消状态的一部分,然后撤消命令只会与数据相关联。

于 2010-09-03T18:28:40.593 回答