Implementing Undo - Redo Functionality in Qt?

2020-06-03 05:09发布

My program consists of multiple QLineEdit's in my QMainWindow. The user can change the text in any QLineEdit. Currently I can perform undo-redo by the default implementation for each QLineEdit when the respective QLineEdit is selected. However I want to add functionality so that when my undo *redo* buttons are pressed then, correspondingly the edited QLineEdit performs undo/redo. i.e. say L1, L2, etc are my QLineEdit's. Then the following operations are done by the user: 1. L2->text added ... 5. L5->text added ... 9. L3->text deleted 10. L5->undo (by selecting L5 & then "ctrl + z")

Now when the user presses Undo/Redo button as follows: 1. Undo -> Should undo the undo performed in step 10 2. Undo -> Should undo the text deleted in step 9 3. Redo -> Should redo the text deleted in step 9 4. Undo -> Should undo the operation done by step 8

Currently I can vaguely think of a mechanism of mainlining the History but it will be pretty tedious. So I would like to know if Qt provides me any inbuilt functionality for doing this? Thank You.

标签: c++ qt
3条回答
我欲成王,谁敢阻挡
2楼-- · 2020-06-03 05:20

Qt provides an Undo/Redo framework.

You basically implement a command, derived from QUndoCommand, for each of the actions you want to make undoable/redoable, and then push them to a QUndoStack. Later, the commands can be undone and redone by calling the corresponding slots on the QUndoStack.

Note that, when pushing a command on the stack, it is automatically redone, means executed for the first time. Sometimes this is not what you want, since the command might actually already have been executed - you would need to consider this in the implementation of your commands.

查看更多
家丑人穷心不美
3楼-- · 2020-06-03 05:24

Qt has classes to help with undo, see QUndoStack. Each undoable step should be implemented as a subclass of QUndoCommand.

What you're trying to achieve is not straightforward because you will need to bypass the internal undo stacks of your QLineEdits. Here's one suggestion: listen for the focusChanged signal from QApplication. If one of your line edits has focus store it's content and connect to the QLineEdit::editingFinished() signal. When this is received put a command on the stack with the old and the new text. The flaw in this approach is that you will not capture intermediate edits in a single QLineEdit. For example if you wanted to store 1) the user selecting text and hitting delete, then 2) typing some new text, as separate undoable steps you might need to start filtering key events and the logic can get quite complex. But that's the general approach.

查看更多
爷的心禁止访问
4楼-- · 2020-06-03 05:26

One way of implementing this is by using the 'Command' pattern. Qt provides an undo framework that follows this pattern: http://qt-project.org/doc/qt-4.8/tools-undoframework.html

To facilitate this, it you may need to make some changes to you program to make it a bit more MVC (model-view-controller). You'd have a data model that represents the contents of your form. The form itself is the view and the controller - any changes to the line edits made by the user would update the data model. The data model would implement changes to it using QUndoCommands which are pushed onto a QUndoStack from the Qt undo framework. When the state of the model changes (due to undo/redo), the UI would respond to the change and be updated to reflect the model's state.

查看更多
登录 后发表回答