QList<QList<QList<QVariant>>> m_tableState; // 保存表格状态的数据结构
int m_indexList; //上面链表的下标,改变下标判断是撤回还是恢复
1.表格内容改变时给信号,保存数据:
connect(this, &CustomTableWidget::itemChanged, this, &CustomTableWidget::saveTableState);
void CustomTableWidget::saveTableState() // 在表格发生修改时保存状态
{
if (m_tableState.isEmpty())//给个初始的空值
{
QList<QList<QVariant>> newState;
for (int row = 0; row < rowCount(); ++row) {
QList<QVariant> rowData;
for (int col = 0; col < columnCount(); ++col) {
rowData.append(QVariant());
}
newState.append(rowData);
}
m_tableState.append(newState);
}
QList<QList<QVariant>> newState;
int rowC = rowCount();
int columnC = columnCount();
bool isChange = checkTableContent();//检查表格内容
if (!isChange) return;
for (int row = 0; row < rowC; ++row) {
QList<QVariant> rowData;
for (int col = 0; col < columnC; ++col) {
QTableWidgetItem *item = this->item(row, col);
rowData.append(item ? item->data(Qt::DisplayRole) : QVariant());
if(item)qDebug() << "item Data" << item->data(Qt::DisplayRole);
}
newState.append(rowData);
}
m_tableState.append(newState);
m_indexList++;
}
判断表格内容是否有修改,没有就返回false不保存到链表
bool CustomTableWidget::checkTableContent()
{
if (m_tableState.isEmpty())
{
return true;
}
for (int row = 0; row < rowCount(); ++row) {
for (int col = 0; col < columnCount(); ++col) {
QTableWidgetItem *item = this->item(row, col);
if (item != nullptr && item->text() != m_tableState.last()[row][col]) {
qDebug() << "Table content changed!";
return true;
}
}
}
return false;
}
2.自定义表格类:class CustomTableWidget : public QTableWidget; 重写键盘事件:
void CustomTableWidget::keyPressEvent(QKeyEvent *event)
{
if (event->modifiers() == Qt::ControlModifier && event->key() == Qt::Key_Z) //ctrl + z
{
int add = -1;//给个参数来移动下标
undoTableState(add);
}
else if (event->modifiers() == Qt::ControlModifier && event->key() == Qt::Key_Y)//ctrl+Y
{
int add = 1;
undoTableState(add);
}
}
3.依据键盘操作,获取链表当前层级的数据:
void CustomTableWidget::undoTableState(int add)
{
if (m_tableState.count() < 2) {
return;
}
// 阻止信号的发射
this->blockSignals(true);
m_indexList += add;
// 恢复上一个状态
if (m_indexList < m_tableState.size() && m_indexList >= 0)
{
QList<QList<QVariant>> prevState = m_tableState[m_indexList];
restoreTableState(prevState);
}
else
{
m_indexList -= add;
}
// 允许信号的发射
this->blockSignals(false);
}
4.获取到当前的层级数据后,调用restoreTableState() 函数,进行显示处理
void CustomTableWidget::restoreTableState(const QList<QList<QVariant>> &state)
{
clearContents();
setRowCount(state.count());
for (int row = 0; row < state.count(); ++row) {
QList<QVariant> rowData = state.at(row);
this->setVerticalHeaderItem(row, new QTableWidgetItem(QString::number(row + 1)));
for (int col = 0; col < rowData.count(); ++col) {
const QVariant &data = rowData.at(col);
QTableWidgetItem *item = new QTableWidgetItem(data.toString());
setItem(row, col, item);
}
}
}