Qt: プログラミング初心者でも安心! QWizard::back() を使って簡単操作のウィザードを作成


QWizard::back() メソッドは、Qt Widgets ライブラリで提供されるウィザードクラスにおいて、現在のウィザードページから前のページへ遷移するために使用されます。このメソッドは、ユーザーがウィザードのバックボタンをクリックしたときに自動的に呼び出されるほか、プログラムコードからも直接呼び出すことができます。

構文

void back();

機能

back() メソッドを実行すると、以下の処理が行われます。

  1. 現在のウィザードページから前のウィザードページへ遷移します。
  2. 前のウィザードページの initializePage() メソッドが呼び出されます。
  3. 前のウィザードページの showPage() メソッドが呼び出されます。

戻り値

なし

QWizard wizard;
wizard.addPage(new MyWizardPage1);
wizard.addPage(new MyWizardPage2);
wizard.addPage(new MyWizardPage3);

connect(wizard, &QWizard::customButtonClicked, this, &MyClass::handleCustomButtonClicked);

wizard.exec();

void MyClass::handleCustomButtonClicked(int id) {
  if (id == QWizard::BackButton) {
    // バックボタンがクリックされた場合の処理
    if (wizard.currentPage() == wizard.page(1)) {
      // 現在のページが 2 番目のページ (MyWizardPage2) の場合
      // 何らかの処理を行う
    }
  }
}

この例では、handleCustomButtonClicked() スロットが QWizard::BackButton シグナルに接続されています。このシグナルは、ユーザーがウィザードのバックボタンをクリックしたときに発行されます。

handleCustomButtonClicked() スロット内では、現在のページが 2 番目のページ (MyWizardPage2) であるかどうかを確認します。もしそうであれば、何らかの処理を行います。

  • back() メソッドは、next() メソッドとは異なり、ウィザードの完了シグナルを発行しません。
  • back() メソッドは、ウィザードが非モーダルである場合にのみ使用できます。モーダルウィザードでは、back() メソッドは呼び出せません。
  • back() メソッドは、最初のページから前に遷移することはできません。


前のページに戻る際の確認ダイアログを表示

#include <QDialog>
#include <QMessageBox>
#include <QWizard>

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

protected:
    virtual void back() override;
};

MyWizard::MyWizard(QWidget *parent) : QWizard(parent)
{
    addPage(new MyWizardPage1);
    addPage(new MyWizardPage2);
    addPage(new MyWizardPage3);
}

void MyWizard::back()
{
    if (QMessageBox::question(this, tr("確認"),
                             tr("前のページに戻りますか?"),
                             QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
        QWizard::back();
    }
}

特定のページまで戻る

この例では、back() メソッドを複数回連続して呼び出し、特定のページまで戻ります。

#include <QWizard>

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

protected:
    virtual void back() override;
};

MyWizard::MyWizard(QWidget *parent) : QWizard(parent)
{
    addPage(new MyWizardPage1);
    addPage(new MyWizardPage2);
    addPage(new MyWizardPage3);
}

void MyWizard::back()
{
    while (currentPage() != page(1)) {
        QWizard::back();
    }
}

この例では、独自のバックボタンを作成し、そのボタンをクリックしたときに back() メソッドを呼び出します。

#include <QPushButton>
#include <QWizard>

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

protected:
    virtual void initializePage() override;
};

MyWizard::MyWizard(QWidget *parent) : QWizard(parent)
{
    addPage(new MyWizardPage1);
    addPage(new MyWizardPage2);
    addPage(new MyWizardPage3);
}

void MyWizard::initializePage()
{
    if (currentPage() != page(1)) {
        QPushButton *backButton = new QPushButton(tr("戻る"), this);
        connect(backButton, &QPushButton::clicked, this, &MyWizard::back);
        layout()->addWidget(backButton);
    }
}
  • back() メソッド以外にも、next() メソッド、accept() メソッド、reject() メソッドなどのメソッドを使用して、ウィザードの進行を制御することができます。


代替方法

  1. setPage() メソッドを使用する

    setPage() メソッドを使用して、直接的に前のページへ遷移することができます。

    wizard.setPage(wizard.currentPage() - 1);
    

    この方法は、back() メソッドよりもシンプルですが、前のページの initializePage() メソッドや showPage() メソッドが呼び出されないという点に注意が必要です。

  2. シグナルとスロットを使用する

    back() メソッドは、currentChanged(int) シグナルを発行します。このシグナルをスロットに接続することで、前のページへ遷移する処理を独自に実装することができます。

    connect(wizard, &QWizard::currentChanged, this, &MyClass::handleCurrentChanged);
    
    void MyClass::handleCurrentChanged(int currentIndex) {
      if (currentIndex < wizard.currentPage() - 1) {
        // 前のページへ遷移する処理
        wizard.setPage(currentIndex);
      }
    }
    

    この方法は、back() メソッドよりも柔軟な制御が可能ですが、コード量が増えるという点に注意が必要です。

  3. customButtonClicked() シグナルを使用する

    customButtonClicked(int) シグナルは、ウィザードのボタンがクリックされたときに発行されます。このシグナルをスロットに接続することで、バックボタン以外のボタンをクリックしたときに前のページへ遷移する処理を独自に実装することができます。

    connect(wizard, &QWizard::customButtonClicked, this, &MyClass::handleCustomButtonClicked);
    
    void MyClass::handleCustomButtonClicked(int id) {
      if (id == MyWizard::BackButton) {
        // 前のページへ遷移する処理
        wizard.setPage(wizard.currentPage() - 1);
      }
    }
    

    この方法は、特定のボタンをクリックしたときにのみ前のページへ遷移する場合に有効です。

どの方法を選択すべきか

どの方法を選択すべきかは、状況によって異なります。

  • 特定のボタンをクリックしたときにのみ前のページへ遷移する必要がある場合は、customButtonClicked() シグナルを使用するのがおすすめです。
  • より柔軟な制御が必要な場合は、シグナルとスロットを使用するのがおすすめです。
  • シンプルで分かりやすい方法が必要な場合は、setPage() メソッドを使用するのがおすすめです。
  • どの方法を選択する場合でも、前のページの initializePage() メソッドや showPage() メソッドが呼び出されないという点に注意する必要があります。
  • 上記以外にも、back() メソッドの代替方法として、独自のウィザードクラスを作成する方法があります。