c++实现qtableview复杂表格支持撤销回退CustomTableModel::onStackChanged
时间: 2024-01-07 07:05:00 浏览: 77
C++课设:基于QT实现教务管理系统.zip
对于支持撤销回退的QTableView复杂表格,可以通过自定义QAbstractTableModel来实现。实现步骤如下:
1. 自定义一个CustomTableModel类,继承自QAbstractTableModel,并在其中添加一个QStack<QStringList>类型的成员变量m_stack,用于存储表格中的操作历史记录。
2. 在CustomTableModel类的构造函数中初始化m_stack,将初始状态的表格数据加入历史记录中。
3. 实现CustomTableModel类的rowCount()和columnCount()函数,分别返回表格的行数和列数。
4. 实现CustomTableModel类的data()函数,根据传入的index参数获取表格中指定单元格的数据,并返回。
5. 实现CustomTableModel类的setData()函数,将表格中指定单元格的数据更新,并将更新后的数据添加到历史记录中。
6. 实现CustomTableModel类的undo()函数和redo()函数,分别用于撤销和恢复表格中的操作历史记录。
7. 在CustomTableModel类中添加一个槽函数onStackChanged(),当历史记录发生变化时,更新表格中的数据。
8. 在QTableView中使用CustomTableModel作为模型,并连接CustomTableModel的信号和槽函数,以实现撤销和恢复操作。
下面是一个示例代码,用于演示如何实现支持撤销回退的QTableView复杂表格:
```c++
class CustomTableModel : public QAbstractTableModel
{
Q_OBJECT
public:
CustomTableModel(QObject *parent = nullptr)
: QAbstractTableModel(parent)
{
m_stack.push_back(QStringList() << "A" << "B" << "C");
}
int rowCount(const QModelIndex &parent = QModelIndex()) const override
{
return m_stack.size();
}
int columnCount(const QModelIndex &parent = QModelIndex()) const override
{
return m_stack[0].size();
}
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override
{
if (role != Qt::DisplayRole)
return QVariant();
if (index.isValid() && index.row() < m_stack.size() && index.column() < m_stack[index.row()].size())
return m_stack[index.row()][index.column()];
return QVariant();
}
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override
{
if (index.isValid() && index.row() < m_stack.size() && index.column() < m_stack[index.row()].size() && role == Qt::EditRole)
{
QString oldValue = m_stack[index.row()][index.column()];
QString newValue = value.toString();
if (oldValue != newValue)
{
QStringList row = m_stack[index.row()];
row.replace(index.column(), newValue);
m_stack.push_back(row);
// emit dataChanged(index, index, {role});
emit dataChanged(createIndex(0, 0), createIndex(m_stack.size() - 1, m_stack[0].size() - 1), {role});
return true;
}
}
return false;
}
void undo()
{
if (m_stack.size() > 1)
{
m_stack.pop_back();
emit dataChanged(createIndex(0, 0), createIndex(m_stack.size() - 1, m_stack[0].size() - 1));
}
}
void redo()
{
// TODO: implement redo
}
signals:
void stackChanged();
public slots:
void onStackChanged()
{
emit stackChanged();
}
private:
QStack<QStringList> m_stack;
};
class CustomTableView : public QTableView
{
Q_OBJECT
public:
CustomTableView(QWidget *parent = nullptr)
: QTableView(parent)
{
m_model = new CustomTableModel(this);
setModel(m_model);
connect(m_model, &CustomTableModel::stackChanged, m_model, &CustomTableModel::onStackChanged);
connect(m_model, &CustomTableModel::stackChanged, this, &CustomTableView::onStackChanged);
}
public slots:
void onStackChanged()
{
qDebug() << "Stack changed";
}
private:
CustomTableModel *m_model;
};
```
阅读全文