Qt GUI: プログラミングでundo/redo機能を簡単に実現!QUndoGroup::createUndoAction()の使い方


QUndoGroup::createUndoAction() 関数は、QUndoGroup に属する QUndoStackundo 操作を実行するための QAction オブジェクトを作成します。このアクションは、ユーザーインターフェースに配置して、アプリケーションの undo 機能を手動で実行できるようにします。

構文

QAction *QUndoGroup::createUndoAction(QObject *parent, const QString &prefix = QString()) const;

パラメータ

  • prefix: アクションのテキストに付加するプレフィックス文字列を指定します。省略可能で、その場合は空文字列になります。
  • parent: アクションの親ウィジェットを指定します。省略可能で、その場合は nullptr を渡します。

戻り値

QUndoStackundo 操作を実行するための QAction オブジェクトを返します。操作が実行できない場合は nullptr を返します。

詳細

QUndoGroup::createUndoAction() 関数は、以下の処理を実行します。

  1. アクティブな QUndoStack を取得します。
  2. アクティブな QUndoStackundo 操作が実行可能かどうかを確認します。
  3. 操作が実行可能な場合は、QAction オブジェクトを作成し、そのテキストに undoTextprefix を設定します。
  4. アクションの triggered シグナルに接続し、シグナルがスロットに接続されている場合は、スロットを呼び出して undo 操作を実行します。
  5. 作成した QAction オブジェクトを返します。

QUndoGroup group;
QUndoStack stack;
group.addStack(&stack);

QAction *undoAction = group.createUndoAction(this, tr("Undo"));
undoAction->setIcon(QIcon::fromTheme("edit-undo"));
undoToolBar->addAction(undoAction);

この例では、QUndoGroupQUndoStack を作成し、QUndoGroupQUndoStack を追加します。次に、QUndoGroup::createUndoAction() 関数を使用して、undo** 操作を実行するためのQAction` オブジェクトを作成します。アクションのテキストは "Undo" に設定され、アイコンは "edit-undo" テーマアイコンに設定されます。最後に、作成したアクションをツールバーに追加します。

  • QUndoGroup のアクティブな QUndoStack を変更するには、QUndoGroup::setActiveStack() 関数を使用します。
  • QUndoGroup に属する複数の QUndoStack がある場合、QUndoGroup::createUndoAction() 関数はアクティブな QUndoStackundo 操作を実行します。
  • QUndoGroup::createUndoAction() 関数は、redo 操作を実行するための QAction オブジェクトを作成するために QUndoGroup::createRedoAction() 関数と組み合わせて使用できます。


例 1: テキストエディタ

この例では、シンプルなテキストエディタを作成し、undoredo 操作を実装します。

#include <QApplication>
#include <QMainWindow>
#include <QTextEdit>
#include <QUndoGroup>
#include <QUndoStack>

int main(int argc, char *argv[]) {
  QApplication app(argc, argv);

  QMainWindow window;
  QTextEdit *textEdit = new QTextEdit(&window);
  textEdit->setDockOptions(QDockWidget::DockToTop);
  window.setCentralWidget(textEdit);

  QUndoGroup group;
  QUndoStack stack;
  group.addStack(&stack);

  QToolBar *toolBar = new QToolBar(&window);
  toolBar->addAction(group.createUndoAction(&window));
  toolBar->addAction(group.createRedoAction(&window));
  window.addToolBar(Qt::TopToolBarArea, toolBar);

  window.show();
  return app.exec();
}

このコードは、以下の動作をします。

  1. QApplication オブジェクトを作成します。
  2. QMainWindow オブジェクトを作成し、QTextEdit ウィジェットを中央ウィジェットとして設定します。
  3. QUndoGroupQUndoStack オブジェクトを作成し、QUndoGroupQUndoStack を追加します。
  4. ツールバーを作成し、undoredo アクションを追加します。
  5. QMainWindow ウィジェットを表示します。

例 2: 図形描画アプリケーション

この例では、図形描画アプリケーションを作成し、undoredo 操作を実装します。

#include <QApplication>
#include <QMainWindow>
#include <QPainter>
#include <QMouseEvent>
#include <QUndoGroup>
#include <QUndoStack>
#include <QUndoCommand>

class ShapeCommand : public QUndoCommand {
public:
  ShapeCommand(const QShape &shape, QUndoCommand *parent = nullptr);

  virtual void redo() override;
  virtual void undo() override;

private:
  QShape shape;
};

class ShapeCommand : public QUndoCommand {
public:
  ShapeCommand(const QShape &shape, QUndoCommand *parent = nullptr);

  virtual void redo() override;
  virtual void undo() override;

private:
  QShape shape;
};

class DrawingArea : public QWidget {
public:
  DrawingArea(QWidget *parent = nullptr);

protected:
  void paintEvent(QPaintEvent *event) override;
  void mousePressEvent(QMouseEvent *event) override;
  void mouseMoveEvent(QMouseEvent *event) override;
  void mouseReleaseEvent(QMouseEvent *event) override;

private:
  QUndoGroup group;
  QUndoStack stack;
  QShape currentShape;
  QPoint startPoint;
};

int main(int argc, char *argv[]) {
  QApplication app(argc, argv);

  QMainWindow window;
  DrawingArea *drawingArea = new DrawingArea(&window);
  drawingArea->setDockOptions(QDockWidget::DockToTop);
  window.setCentralWidget(drawingArea);

  QToolBar *toolBar = new QToolBar(&window);
  toolBar->addAction(group.createUndoAction(&window));
  toolBar->addAction(group.createRedoAction(&window));
  window.addToolBar(Qt::TopToolBarArea, toolBar);

  window.show();
  return app.exec();
}
  1. QApplication オブジェクトを作成します。
  2. QMainWindow オブジェクトを作成し、DrawingArea ウィジェットを中央ウィジェットとして設定します。
  3. QUndoGroupQUndoStack オブジェクトを作成し、QUndoGroupQUndoStack を追加します。
  4. ツールバーを作成し、undoredo アクションを追加します。
  5. QMainWindow ウィジェットを表示します。


QUndoGroup::createUndoAction() 以外にも、undo 操作を実行するための方法はいくつかあります。

方法

  • キーボードショートカットを使用する
    アプリケーションにキーボードショートカットを設定して、undo 操作をすばやく実行できるようにできます。
  • カスタムアクションを作成する
    独自のロジックを使用して undo 操作を実行するカスタムアクションを作成できます。
  • **QUndoStack::createUndoAction()関数を使用する:** この関数は、特定のQUndoStackの **undo** 操作を実行するためのQAction` オブジェクトを作成します。

詳細

  • **QUndoStack::createUndoAction()関数:** この関数は、QUndoGroup::createUndoAction()関数とほぼ同じように動作しますが、特定のQUndoStackを対象としたものです。これは、複数のQUndoStackを使用するアプリケーションで、特定のQUndoStack` の undo 操作を個別に制御したい場合に役立ちます。
QAction *undoAction = stack.createUndoAction(this, tr("Undo"));
  • カスタムアクションの作成
    独自のロジックを使用して undo 操作を実行するカスタムアクションを作成できます。これにより、より複雑な undo 操作を実装したり、特定のアプリケーションのニーズに合わせた undo 操作をカスタマイズしたりすることができます。
class MyUndoAction : public QAction {
public:
  MyUndoAction(QObject *parent = nullptr);

protected:
  void triggered() override;
};

MyUndoAction::MyUndoAction(QObject *parent) : QAction(parent) {
  setText(tr("Undo"));
}

void MyUndoAction::triggered() {
  // 独自のロジックを使用して undo 操作を実行する
  // ...
}
  • キーボードショートカットの使用
    アプリケーションにキーボードショートカットを設定して、undo 操作をすばやく実行できるようにできます。これにより、ユーザーインターフェースからアクションを選択する必要がなくなり、操作をより迅速かつ効率的に実行できます。
QShortcut *shortcut = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_Z), this);
connect(shortcut, &QShortcut::activated, this, &MyClass::undo);

上記以外にも、QUndoModelQUndoView などの他の Qt クラスを使用して undo 操作を実装する方法があります。これらのクラスは、より高度な undo/redo 機能を提供するために使用できます。