c++代码实现qtableview支持撤销重做
时间: 2024-01-21 10:18:55 浏览: 92
QTableView 是 Qt 框架中的一种表格视图控件,如果想要支持撤销重做操作,可以在模型中添加相应的实现。以下是一个基于 C++ 的示例代码,演示如何在 QTableView 中支持撤销重做操作。
首先,我们需要定义一个基于 QStandardItemModel 的自定义模型类,这个类需要继承自 QStandardItemModel,同时支持撤销和重做操作。在这个自定义模型类中,我们可以创建一个 QVector 存储所有的操作记录,并使用 QUndoStack 类来实现撤销和重做操作。
```cpp
class CustomTableModel : public QStandardItemModel
{
Q_OBJECT
public:
CustomTableModel(int rows, int columns, QObject *parent = nullptr);
~CustomTableModel();
void setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
bool undo();
bool redo();
private:
QVector<QPair<QModelIndex, QVariant>> m_undoStack;
QVector<QPair<QModelIndex, QVariant>> m_redoStack;
QUndoStack* m_undoRedoStack;
private slots:
void onStackChanged(bool canUndo, bool canRedo);
};
```
在构造函数中,我们初始化了撤销、重做堆栈和 QUndoStack 实例。在 setData 函数中,我们记录了每次修改的操作记录。在 undo 和 redo 函数中,我们通过使用 QUndoStack 实例的 undo 和 redo 函数实现撤销和重做操作。在 onStackChanged 函数中,我们更新了撤销、重做操作的可用性状态。
```cpp
CustomTableModel::CustomTableModel(int rows, int columns, QObject *parent)
: QStandardItemModel(rows, columns, parent)
{
m_undoRedoStack = new QUndoStack(this);
connect(m_undoRedoStack, &QUndoStack::canUndoChanged, this, &CustomTableModel::onStackChanged);
connect(m_undoRedoStack, &QUndoStack::canRedoChanged, this, &CustomTableModel::onStackChanged);
}
CustomTableModel::~CustomTableModel()
{
delete m_undoRedoStack;
}
void CustomTableModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
QStandardItemModel::setData(index, value, role);
QPair<QModelIndex, QVariant> data(index, value);
m_undoStack.append(data);
m_redoStack.clear();
QUndoCommand* command = new QUndoStack::CustomUndoCommand(m_undoStack, m_redoStack, this);
m_undoRedoStack->push(command);
}
bool CustomTableModel::undo()
{
if (m_undoRedoStack->canUndo()) {
m_undoRedoStack->undo();
return true;
}
return false;
}
bool CustomTableModel::redo()
{
if (m_undoRedoStack->canRedo()) {
m_undoRedoStack->redo();
return true;
}
return false;
}
void CustomTableModel::onStackChanged(bool canUndo, bool canRedo)
{
emit undoAvailable(canUndo);
emit redoAvailable(canRedo);
}
```
最后,我们需要在窗口中创建一个 QTableView 实例,并将自定义模型类设置为它的数据模型。我们还需要为撤销和重做操作创建相应的槽函数,并将它们与窗口中的按钮信号连接。
```cpp
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
CustomTableModel* m_model;
private slots:
void onUndo();
void onRedo();
};
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
m_model = new CustomTableModel(3, 2, this);
ui->tableView->setModel(m_model);
connect(ui->undoButton, &QPushButton::clicked, this, &MainWindow::onUndo);
connect(ui->redoButton, &QPushButton::clicked, this, &MainWindow::onRedo);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::onUndo()
{
m_model->undo();
}
void MainWindow::onRedo()
{
m_model->redo();
}
```
通过这个示例代码,我们可以在 QTableView 中实现撤销重做操作。当用户对表格中的单元格进行修改时,可以将这个修改操作记录下来,并将操作记录添加到撤销堆栈中。当用户点击撤销按钮时,我们可以从撤销堆栈中取出最后一次操作,将其还原到表格中,并将其添加到重做堆栈中。当用户点击重做按钮时,我们可以从重做堆栈中取出最后一次操作,并将其添加到撤销堆栈中。
阅读全文