c++ qtreewidget和qtablewidget支持撤销与恢复功能 代码qundogroup
时间: 2024-02-20 09:01:54 浏览: 180
以下是使用 `QUndoStack` 实现 `QTreeWidget` 和 `QTableWidget` 的撤销与恢复功能的示例代码:
```cpp
#include <QApplication>
#include <QMainWindow>
#include <QUndoStack>
#include <QTreeWidget>
#include <QTableWidget>
#include <QHeaderView>
class UndoCommand : public QUndoCommand
{
public:
explicit UndoCommand(QTreeWidgetItem *item, const QString &text, QUndoCommand *parent = nullptr)
: QUndoCommand(parent), m_item(item), m_oldText(item->text(0)), m_newText(text)
{
}
void undo() override
{
m_item->setText(0, m_oldText);
}
void redo() override
{
m_item->setText(0, m_newText);
}
private:
QTreeWidgetItem *m_item;
QString m_oldText;
QString m_newText;
};
class TreeWidget : public QTreeWidget
{
Q_OBJECT
public:
explicit TreeWidget(QWidget *parent = nullptr) : QTreeWidget(parent)
{
m_undoStack = new QUndoStack(this);
}
protected:
void keyPressEvent(QKeyEvent *event) override
{
if (event->key() == Qt::Key_Z && (event->modifiers() & Qt::ControlModifier)) {
if (event->modifiers() & Qt::ShiftModifier) {
m_undoStack->redo();
} else {
m_undoStack->undo();
}
event->accept();
} else {
QTreeWidget::keyPressEvent(event);
}
}
void mousePressEvent(QMouseEvent *event) override
{
if (event->button() == Qt::LeftButton) {
m_lastItem = currentItem();
}
QTreeWidget::mousePressEvent(event);
}
void mouseReleaseEvent(QMouseEvent *event) override
{
if (event->button() == Qt::LeftButton) {
auto item = currentItem();
if (item && item == m_lastItem) {
auto text = item->text(0);
auto newText = QInputDialog::getText(this, tr("Edit"), tr("Text:"), QLineEdit::Normal, text);
if (!newText.isEmpty() && newText != text) {
auto cmd = new UndoCommand(item, newText);
m_undoStack->push(cmd);
}
}
}
QTreeWidget::mouseReleaseEvent(event);
}
private:
QUndoStack *m_undoStack;
QTreeWidgetItem *m_lastItem;
};
class TableWidget : public QTableWidget
{
Q_OBJECT
public:
explicit TableWidget(QWidget *parent = nullptr) : QTableWidget(parent)
{
m_undoStack = new QUndoStack(this);
}
protected:
void keyPressEvent(QKeyEvent *event) override
{
if (event->key() == Qt::Key_Z && (event->modifiers() & Qt::ControlModifier)) {
if (event->modifiers() & Qt::ShiftModifier) {
m_undoStack->redo();
} else {
m_undoStack->undo();
}
event->accept();
} else {
QTableWidget::keyPressEvent(event);
}
}
void mousePressEvent(QMouseEvent *event) override
{
if (event->button() == Qt::LeftButton) {
m_lastItem = itemAt(event->pos());
}
QTableWidget::mousePressEvent(event);
}
void mouseReleaseEvent(QMouseEvent *event) override
{
if (event->button() == Qt::LeftButton) {
auto item = itemAt(event->pos());
if (item && item == m_lastItem) {
auto text = item->text();
auto newText = QInputDialog::getText(this, tr("Edit"), tr("Text:"), QLineEdit::Normal, text);
if (!newText.isEmpty() && newText != text) {
auto cmd = new UndoCommand(item, newText);
m_undoStack->push(cmd);
}
}
}
QTableWidget::mouseReleaseEvent(event);
}
private:
QUndoStack *m_undoStack;
QTableWidgetItem *m_lastItem;
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QMainWindow mainWindow;
auto treeWidget = new TreeWidget(&mainWindow);
auto tableWidget = new TableWidget(&mainWindow);
treeWidget->setHeaderLabel("Tree Widget");
tableWidget->horizontalHeader()->setStretchLastSection(true);
tableWidget->setRowCount(3);
tableWidget->setColumnCount(2);
tableWidget->setHorizontalHeaderLabels({"Column 1", "Column 2"});
tableWidget->setItem(0, 0, new QTableWidgetItem("Item 1-1"));
tableWidget->setItem(0, 1, new QTableWidgetItem("Item 1-2"));
tableWidget->setItem(1, 0, new QTableWidgetItem("Item 2-1"));
tableWidget->setItem(1, 1, new QTableWidgetItem("Item 2-2"));
tableWidget->setItem(2, 0, new QTableWidgetItem("Item 3-1"));
tableWidget->setItem(2, 1, new QTableWidgetItem("Item 3-2"));
mainWindow.setCentralWidget(treeWidget);
mainWindow.addDockWidget(Qt::RightDockWidgetArea, new QDockWidget("Table Widget", &mainWindow));
mainWindow.centralWidget()->setMinimumSize(400, 300);
mainWindow.dockWidgetAreaChanged(Qt::RightDockWidgetArea);
auto tableWidgetContainer = new QWidget(&mainWindow);
auto tableWidgetLayout = new QVBoxLayout(tableWidgetContainer);
tableWidgetLayout->setMargin(0);
tableWidgetLayout->addWidget(tableWidget);
mainWindow.findChild<QDockWidget*>("Table Widget")->setWidget(tableWidgetContainer);
mainWindow.show();
return a.exec();
}
#include "main.moc"
```
在这个示例中,我们继承了 `QTreeWidget` 和 `QTableWidget` 类,重写了 `keyPressEvent` 和 `mousePressEvent` 方法,以便在用户按下 `Ctrl+Z` 或单击一个单元格时执行撤销和恢复操作。我们还创建了一个 `UndoCommand` 类,以便保存撤销和恢复所需的数据。最后,我们将 `QTreeWidget` 和 `QTableWidget` 放在一个 `QMainWindow` 中,以便测试这些小部件。
阅读全文