在Qt中实现撤消 - 重做功能?

时间:2013-02-21 09:37:15

标签: c++ qt

我的程序由QLineEdit中的多个QMainWindow组成。用户可以更改任何QLineEdit中的文本。目前,当选择了相应的QLineEdit时,我可以通过默认实现为每个QLineEdit执行 undo-redo 。但是我想添加功能,以便在按下 undo * redo *按钮时,相应地,编辑后的QLineEdit执行 undo / redo 。即说L1,L2等是我的QLineEdit。然后用户完成以下操作: 1.添加了L2->文本 ... 5.添加了L5->文本 ... 9.删除L3->文本 10. L5->撤消(通过选择L5&然后“ctrl + z”)

现在,当用户按下撤消/重做按钮时,如下所示: 1.撤消 - >应该撤消在步骤10中执行的撤消 2.撤消 - >应撤消在步骤9中删除的文本 3.重做 - >应重做在步骤9中删除的文本 4.撤消 - >应该撤消第8步完成的操作

目前,我可以模糊地想到一种主导历史的机制,但这将是相当繁琐的。所以我想知道Qt是否为我提供了任何内置功能? 谢谢。

3 个答案:

答案 0 :(得分:12)

Qt提供Undo/Redo框架。

您基本上为每个要撤消/可重做的操作实现一个派生自QUndoCommand的命令,然后将它们推送到QUndoStack。稍后,可以通过调用QUndoStack上的相应插槽来撤消和重做命令。

请注意,在堆栈上按下命令时,它会自动重做,这意味着第一次执行。有时这不是你想要的,因为命令实际上可能已经被执行了 - 你需要在执行命令时考虑这个。

答案 1 :(得分:3)

实现此目的的一种方法是使用“命令”模式。 Qt提供了一个遵循这种模式的撤销框架: http://qt-project.org/doc/qt-4.8/tools-undoframework.html

为方便起见,您可能需要对程序进行一些更改以使其更加MVC(模型 - 视图 - 控制器)。您将拥有一个表示表单内容的数据模型。表单本身就是视图和控制器 - 用户对行编辑的任何更改都将更新数据模型。数据模型将使用QUndoCommands实现对它的更改,QUndoCommands从Qt撤消框架推送到QUndoStack。当模型的状态发生变化时(由于撤消/重做),UI将响应更改并更新以反映模型的状态。

答案 2 :(得分:1)

Qt有帮助撤消的课程,请参阅QUndoStack。每个可撤销步骤都应实现为QUndoCommand的子类。

您尝试实现的目标并不简单,因为您需要绕过QLineEdit的内部撤消堆栈。以下是一条建议:收听来自focusChanged的{​​{1}}信号。如果您的某个行修改具有焦点,则将其内容存储并连接到QApplication信号。收到此消息时,在堆栈中使用旧文本和新文本放置命令。这种方法的缺陷是您不会在单个QLineEdit::editingFinished()中捕获中间编辑。例如,如果您想存储1)用户选择文本并点击删除,那么2)键入一些新文本,作为单独的可撤销步骤,您可能需要开始过滤关键事件,逻辑可能变得非常复杂。但这是一般方法。