c++代码实现qtreewidget和qtableview支持撤销重做
时间: 2023-09-09 18:07:55 浏览: 157
实现QTreeWidget和QTableView支持撤销重做,需要用到Qt提供的QUndoStack类。QUndoStack是一个用于实现撤销和重做操作的类,它可以在操作之前存储操作状态,并在需要时进行恢复。下面是一个简单的示例代码:
```cpp
#include <QApplication>
#include <QUndoStack>
#include <QUndoCommand>
#include <QTreeView>
#include <QTableView>
#include <QStandardItemModel>
class TreeModelCommand: public QUndoCommand
{
public:
TreeModelCommand(QTreeView* treeView, QStandardItemModel* model, int row,
QStandardItem* item, QUndoCommand* parent = nullptr):
QUndoCommand(parent),
m_treeView(treeView),
m_model(model),
m_row(row),
m_item(item)
{
}
void undo() override
{
m_model->removeRow(m_row);
m_treeView->setCurrentIndex(QModelIndex());
}
void redo() override
{
m_model->insertRow(m_row, m_item);
m_treeView->setCurrentIndex(m_model->index(m_row, 0));
}
private:
QTreeView* m_treeView;
QStandardItemModel* m_model;
int m_row;
QStandardItem* m_item;
};
class TableModelCommand: public QUndoCommand
{
public:
TableModelCommand(QTableView* tableView, QStandardItemModel* model, int row,
int column, const QVariant& data, QUndoCommand* parent = nullptr):
QUndoCommand(parent),
m_tableView(tableView),
m_model(model),
m_row(row),
m_column(column),
m_data(data)
{
}
void undo() override
{
m_model->setData(m_model->index(m_row, m_column), m_oldData);
m_tableView->setCurrentIndex(QModelIndex());
}
void redo() override
{
m_oldData = m_model->data(m_model->index(m_row, m_column));
m_model->setData(m_model->index(m_row, m_column), m_data);
m_tableView->setCurrentIndex(m_model->index(m_row, m_column));
}
private:
QTableView* m_tableView;
QStandardItemModel* m_model;
int m_row;
int m_column;
QVariant m_data;
QVariant m_oldData;
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QUndoStack undoStack;
QTreeView treeView;
QStandardItemModel treeModel;
treeView.setModel(&treeModel);
QTableView tableView;
QStandardItemModel tableModel;
tableView.setModel(&tableModel);
QObject::connect(&treeModel, &QStandardItemModel::itemChanged, [&undoStack, &treeView, &treeModel](QStandardItem* item) {
auto command = new TreeModelCommand(&treeView, &treeModel, item->row(), item);
undoStack.push(command);
});
QObject::connect(&tableModel, &QStandardItemModel::dataChanged, [&undoStack, &tableView, &tableModel](const QModelIndex& index, const QVariant& data, const QVariant& oldData) {
auto command = new TableModelCommand(&tableView, &tableModel, index.row(), index.column(), data);
undoStack.push(command);
});
treeModel.appendRow(new QStandardItem("Item 1"));
treeModel.appendRow(new QStandardItem("Item 2"));
tableModel.setItem(0, 0, new QStandardItem("1"));
tableModel.setItem(0, 1, new QStandardItem("One"));
tableModel.setItem(1, 0, new QStandardItem("2"));
tableModel.setItem(1, 1, new QStandardItem("Two"));
treeView.show();
tableView.show();
return a.exec();
}
```
在上面的示例代码中,我们定义了两个QUndoCommand子类分别用于实现QTreeWidget和QTableView的撤销和重做操作。这两个类都继承自QUndoCommand类,并实现了undo()和redo()方法,这两个方法分别用于撤销和重做当前操作。在这两个类的构造函数中,我们保存了操作所需的数据以便于undo()和redo()方法的实现。
在main()函数中,我们创建了一个QUndoStack对象来存储所有操作,并将其与QTreeWidget和QTableView的数据模型的信号连接起来。当QStandardItemModel的itemChanged信号被触发时,我们创建一个TreeModelCommand对象并将其压入undoStack中。当QStandardItemModel的dataChanged信号被触发时,我们创建一个TableModelCommand对象并将其压入undoStack中。
最后,我们通过调用show()方法来显示QTreeWidget和QTableView,并通过调用QApplication的exec()方法启动应用程序。
阅读全文