c++ 通过QUndoGroup实现qtreewidget和qtablewidget支持撤销与恢复功能 代码
时间: 2024-02-20 18:02:14 浏览: 65
Qt QDockWidget、QtreeWidget界面实现
以下是通过QUndoGroup实现QTreeWidget和QTableWidget支持撤销与恢复功能的代码示例:
```
#include <QtWidgets>
class TreeWidgetItem : public QTreeWidgetItem
{
public:
explicit TreeWidgetItem(QTreeWidget *parent = nullptr)
: QTreeWidgetItem(parent)
{
}
void setData(int column, int role, const QVariant &value) override
{
QUndoCommand *cmd = new TreeWidgetItemDataCommand(this, column, role, text(column), value.toString());
cmd->setText(QString("Edit %1 \"%2\" to \"%3\"").arg(parent()->objectName(), text(column), value.toString()));
undoStack()->push(cmd);
}
QUndoStack *undoStack() const
{
return treeWidget()->property("undoStack").value<QUndoStack *>();
}
};
class TreeWidgetItemDataCommand : public QUndoCommand
{
public:
explicit TreeWidgetItemDataCommand(TreeWidgetItem *item, int column, int role, const QString &oldValue, const QString &newValue)
: item(item), column(column), role(role), oldValue(oldValue), newValue(newValue)
{
}
void undo() override
{
item->setText(column, oldValue);
}
void redo() override
{
item->setText(column, newValue);
}
private:
TreeWidgetItem *item;
int column;
int role;
QString oldValue;
QString newValue;
};
class TableWidgetItem : public QTableWidgetItem
{
public:
explicit TableWidgetItem(QTableWidget *parent = nullptr)
: QTableWidgetItem(parent)
{
}
void setData(int role, const QVariant &value) override
{
QUndoCommand *cmd = new TableWidgetItemDataCommand(this, role, data(role), value.toString());
cmd->setText(QString("Edit %1 \"%2\" to \"%3\"").arg(parent()->objectName(), data(Qt::DisplayRole).toString(), value.toString()));
undoStack()->push(cmd);
}
QUndoStack *undoStack() const
{
return tableWidget()->property("undoStack").value<QUndoStack *>();
}
};
class TableWidgetItemDataCommand : public QUndoCommand
{
public:
explicit TableWidgetItemDataCommand(TableWidgetItem *item, int role, const QString &oldValue, const QString &newValue)
: item(item), role(role), oldValue(oldValue), newValue(newValue)
{
}
void undo() override
{
item->setData(role, oldValue);
}
void redo() override
{
item->setData(role, newValue);
}
private:
TableWidgetItem *item;
int role;
QString oldValue;
QString newValue;
};
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QUndoGroup undoGroup;
// 创建 QTreeWidget
QTreeWidget treeWidget;
treeWidget.setObjectName("TreeWidget");
treeWidget.setProperty("undoStack", QVariant::fromValue(&undoGroup.createUndoStack()));
// 创建 QTableWidget
QTableWidget tableWidget;
tableWidget.setObjectName("TableWidget");
tableWidget.setProperty("undoStack", QVariant::fromValue(&undoGroup.createUndoStack()));
tableWidget.setColumnCount(2);
tableWidget.setRowCount(2);
// 添加测试数据
treeWidget.setHeaderLabels({"Name", "Value"});
QTreeWidgetItem *root = new QTreeWidgetItem(&treeWidget, {"Root"});
TreeWidgetItem *child1 = new TreeWidgetItem(root);
child1->setText(0, "Child 1");
child1->setText(1, "1");
TreeWidgetItem *child2 = new TreeWidgetItem(root);
child2->setText(0, "Child 2");
child2->setText(1, "2");
tableWidget.setItem(0, 0, new TableWidgetItem(&tableWidget));
tableWidget.setItem(0, 1, new TableWidgetItem(&tableWidget));
tableWidget.setItem(1, 0, new TableWidgetItem(&tableWidget));
tableWidget.setItem(1, 1, new TableWidgetItem(&tableWidget));
// 创建一个窗口并显示
QMainWindow window;
window.setCentralWidget(&treeWidget);
window.setMenuBar(new QMenuBar);
window.menuBar()->addAction(undoGroup.createUndoAction(&window));
window.menuBar()->addAction(undoGroup.createRedoAction(&window));
window.show();
return app.exec();
}
```
在上面的代码中,我们创建了两个自定义的QTreeWidgetItem和QTableWidgetItem类,用于处理数据更改操作。这些类都继承了QUndoCommand类,以便我们可以将更改操作添加到QUndoStack中。
我们还使用QTreeWidget和QTableWidget的setProperty方法将undoStack属性设置为创建的QUndoStack对象。这使得我们可以通过使用undoStack()方法来获取当前对象的QUndoStack对象。
最后,我们创建了一个窗口并将其显示出来。我们将撤销和重做操作添加到菜单栏中,以便用户可以轻松地撤销和恢复更改操作。
阅读全文