2013-02-21 567 views
7

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

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

目前我可以隐约想到一个主线历史的机制,但它会非常乏味。所以我想知道Qt是否为我提供了任何内置功能? 谢谢。

回答

9

Qt提供了一个Undo/Redo框架。

对于要进行撤销/重做的每个操作,您基本上都会执行一条从QUndoCommand派生的命令,然后将它们推送到QUndoStack。稍后,可以通过调用QUndoStack上的相应插槽来撤销和重做命令。

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

+0

谢谢您的回答和您对该主题的意见! – 2013-02-21 10:07:42

3

实现此目的的一种方法是使用“命令”模式。 Qt提供了一种遵循以下模式的撤消框架:为了便于实现,您可能需要对程序进行一些更改以使其更加MVC(模型视图控制器)。你需要一个表示表单内容的数据模型。表单本身就是视图和控制器 - 用户对行编辑所做的任何更改都会更新数据模型。数据模型将使用从Qt撤销框架中推送到QUndoStack的QUndoCommands来实现对其的更改。当模型的状态发生变化时(由于撤销/重做),UI将响应该变化并进行更新以反映模型的状态。

+0

谢谢你的回答。我会研究这一点。但我不能直接明白你的意思是MVC。这是一个Qt概念还是一个普通的程序? – 2013-02-21 10:08:58

+1

MVC是一个通用的编程概念。视图和控制器部分在这里有些耦合 - 在GUI程序中经常出现这种情况。从本质上讲,可以将其视为从用户界面分割数据。 UI显示并控制数据。 – Pete 2013-02-21 12:16:10

+2

你也可以确保Ctrl-Z等是通过你的撤消/重做动作而不是通过QLineEdits来完成的,这样它才能正确地启动。 – Pete 2013-02-21 12:16:59

1

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

您试图实现的目标并不简单,因为您需要绕过QLineEdit的内部撤消堆栈。这里有一个建议:倾听来自QApplicationfocusChanged信号。如果您的一行编辑有焦点商店,它的内容并连接到QLineEdit::editingFinished()信号。收到此信息时,将命令放在新旧文本的堆栈上。这种方法的缺陷在于,您不会在一个QLineEdit中捕获中间编辑。例如,如果您想要存储1)用户选择文本并点击删除,然后2)键入一些新文本,作为单独的可撤销步骤,您可能需要开始过滤关键事件,并且逻辑可能变得非常复杂。但这是一般的方法。

+0

谢谢您的回答,并提供您的建议。我会研究它,如果有任何问题,请回复你。 – 2013-02-21 10:09:41