QUndoView 本质是一个 Qt 界面控件(继承自 QListView),专门适配 QUndoStack


cpp
#include <QApplication>
#include <QUndoStack>
#include <QUndoCommand>
#include <QUndoView>
#include <QWidget>
#include <QVBoxLayout>
#include <QPushButton>
#include <QLabel>
#include <QDebug>
// 自定义可撤销命令:数字加1
class AddCommand : public QUndoCommand {
public:
AddCommand(int& num, QUndoCommand* parent = nullptr)
: QUndoCommand(parent), m_num(num) {
// 设置操作描述文本(会显示在QUndoView中)
setText(QString("数字加1 (当前值: %1 → %2)").arg(m_num).arg(m_num + 1));
}
void redo() override {
m_num += 1;
}
void undo() override {
m_num -= 1;
}
private:
int& m_num;
};
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
// 1. 初始化核心变量和撤销栈
int num = 0;
QUndoStack undoStack;
// 2. 创建主窗口和布局
QWidget window;
window.setWindowTitle("QUndoView 示例");
QVBoxLayout* layout = new QVBoxLayout(&window);
// 3. 创建显示当前数值的标签
QLabel* numLabel = new QLabel(QString("当前数值: %1").arg(num));
layout->addWidget(numLabel);
// 4. 创建"添加操作"按钮
QPushButton* addBtn = new QPushButton("点击执行「数字加1」");
layout->addWidget(addBtn);
QObject::connect(addBtn, &QPushButton::clicked, [&]() {
// 每次点击压入新的AddCommand
undoStack.push(new AddCommand(num));
// 更新标签显示
numLabel->setText(QString("当前数值: %1").arg(num));
qDebug() << "当前撤销栈大小:" << undoStack.count();
});
// 5. 创建QUndoView并绑定撤销栈
QUndoView* undoView = new QUndoView(&undoStack);
undoView->setWindowTitle("操作历史");
// 设置空栈时的提示文本
undoView->setEmptyLabel("暂无操作记录");
// 调整视图大小
undoView->resize(400, 300);
undoView->show();
// 6. 同步撤销/重做后的数值显示
QObject::connect(&undoStack, &QUndoStack::undoTextChanged, [&]() {
numLabel->setText(QString("当前数值: %1").arg(num));
});
QObject::connect(&undoStack, &QUndoStack::redoTextChanged, [&]() {
numLabel->setText(QString("当前数值: %1").arg(num));
});
// 显示主窗口
window.resize(300, 150);
window.show();
return a.exec();
}