我的程序由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是否为我提供了任何内置功能? 谢谢。
答案 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)键入一些新文本,作为单独的可撤销步骤,您可能需要开始过滤关键事件,逻辑可能变得非常复杂。但这是一般方法。