排他的なボタングループの動作を制御するQAbstractButton::autoExclusiveプロパティ


QAbstractButton::autoExclusiveは、チェック可能なボタンの動作を制御するプロパティです。このプロパティを有効にすると、同じ親ウィジェットに属するチェック可能なボタンは、互いに排他的なグループを形成します。つまり、グループ内の複数のボタンが同時にチェックされることはなく、常に1つのボタンだけがチェックされた状態になります。

利点

  • ラジオボタンやメニューボタンなどの排他的な選択を表現するのに役立ちます。
  • ユーザーが誤って複数のオプションを選択することを防ぎます。
  • ユーザーインターフェースの設計を簡素化できます。

使用方法

QAbstractButton::setAutoExclusive(bool) メソッドを使用して、このプロパティを設定できます。引数 bool は、排他性を有効にする場合は true、無効にする場合は false を設定します。

QRadioButton *radioButton1 = new QRadioButton("Option 1", parentWidget);
QRadioButton *radioButton2 = new QRadioButton("Option 2", parentWidget);

radioButton1->setAutoExclusive(true);
radioButton2->setAutoExclusive(true);

上記のコード例では、radioButton1radioButton2 は同じ親ウィジェットに属し、setAutoExclusive メソッドを使用して排他性を有効にしています。これにより、ユーザーが同時に両方のボタンを選択することはできなくなり、常にいずれか1つのボタンだけがチェックされた状態になります。

  • 排他的なボタングループ内のボタンの状態をプログラムで制御するには、QAbstractButton::setChecked() メソッドを使用できます。
  • このプロパティは、ボタンのグループ化を自動的に処理するため、開発者が手動でグループを管理する必要はありません。
  • QAbstractButton::autoExclusive プロパティは、チェック可能なボタンにのみ適用されます。

以下のコード例は、QAbstractButton::setChecked() メソッドを使用して、排他的なボタングループ内のボタンの状態をプログラムで制御する方法を示しています。

QRadioButton *radioButton1 = new QRadioButton("Option 1", parentWidget);
QRadioButton *radioButton2 = new QRadioButton("Option 2", parentWidget);

radioButton1->setAutoExclusive(true);
radioButton2->setAutoExclusive(true);

radioButton2->setChecked(true); // Option 2 を初期状態としてチェック

上記のコード例では、radioButton2 が初期状態でチェックされ、ユーザーが radioButton1 を選択すると radioButton2 のチェック状態が解除されます。

QAbstractButton::autoExclusive プロパティは、Qt Widgetsにおける排他的なボタングループを簡単に作成するための便利な機能です。このプロパティを使用することで、ユーザーインターフェースの設計を簡素化し、ユーザーの操作ミスを防ぐことができます。



例1: 排他的なラジオボタン

この例では、3つのラジオボタンを作成し、setAutoExclusiveプロパティを使用して排他性を有効にします。ユーザーは、3つのオプションのうち1つを選択することができます。

#include <QApplication>
#include <QRadioButton>
#include <QVBoxLayout>

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

  QWidget *window = new QWidget;
  QVBoxLayout *layout = new QVBoxLayout(window);

  QRadioButton *radioButton1 = new QRadioButton("Option 1", window);
  QRadioButton *radioButton2 = new QRadioButton("Option 2", window);
  QRadioButton *radioButton3 = new QRadioButton("Option 3", window);

  radioButton1->setAutoExclusive(true);
  radioButton2->setAutoExclusive(true);
  radioButton3->setAutoExclusive(true);

  layout->addWidget(radioButton1);
  layout->addWidget(radioButton2);
  layout->addWidget(radioButton3);

  window->setLayout(layout);
  window->show();

  return app.exec();
}

例2: 排他的なメニューボタン

この例では、3つのメニューボタンを作成し、setAutoExclusiveプロパティを使用して排他性を有効にします。ユーザーは、3つのコマンドのうち1つを選択することができます。

#include <QApplication>
#include <QToolButton>
#include <QHBoxLayout>

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

  QWidget *window = new QWidget;
  QHBoxLayout *layout = new QHBoxLayout(window);

  QToolButton *toolButton1 = new QToolButton(window);
  toolButton1->setText("Command 1");
  QToolButton *toolButton2 = new QToolButton(window);
  toolButton2->setText("Command 2");
  QToolButton *toolButton3 = new QToolButton(window);
  toolButton3->setText("Command 3");

  toolButton1->setAutoExclusive(true);
  toolButton2->setAutoExclusive(true);
  toolButton3->setAutoExclusive(true);

  layout->addWidget(toolButton1);
  layout->addWidget(toolButton2);
  layout->addWidget(toolButton3);

  window->setLayout(layout);
  window->show();

  return app.exec();
}


シグナルとスロット

各ボタンの clicked() シグナルを接続し、スロット内でグループ内の他のボタンのチェック状態を解除することができます。

#include <QApplication>
#include <QRadioButton>
#include <QVBoxLayout>

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

  QWidget *window = new QWidget;
  QVBoxLayout *layout = new QVBoxLayout(window);

  QRadioButton *radioButton1 = new QRadioButton("Option 1", window);
  QRadioButton *radioButton2 = new QRadioButton("Option 2", window);
  QRadioButton *radioButton3 = new QRadioButton("Option 3", window);

  connect(radioButton1, &QRadioButton::clicked, [=]() {
    radioButton2->setChecked(false);
    radioButton3->setChecked(false);
  });

  connect(radioButton2, &QRadioButton::clicked, [=]() {
    radioButton1->setChecked(false);
    radioButton3->setChecked(false);
  });

  connect(radioButton3, &QRadioButton::clicked, [=]() {
    radioButton1->setChecked(false);
    radioButton2->setChecked(false);
  });

  layout->addWidget(radioButton1);
  layout->addWidget(radioButton2);
  layout->addWidget(radioButton3);

  window->setLayout(layout);
  window->show();

  return app.exec();
}

カスタムクラス

排他的なボタングループのロジックをカプセル化するカスタムクラスを作成することができます。

#include <QApplication>
#include <QRadioButton>
#include <QVBoxLayout>

class ExclusiveButtonGroup : public QObject {
public:
  ExclusiveButtonGroup(QWidget *parent) : QObject(parent) {}

  void addButton(QRadioButton *button) {
    buttons_.push_back(button);
    connect(button, &QRadioButton::clicked, this, &ExclusiveButtonGroup::onButtonClicked);
  }

private:
  std::vector<QRadioButton *> buttons_;

  void onButtonClicked(QRadioButton *button) {
    for (QRadioButton *otherButton : buttons_) {
      if (otherButton != button) {
        otherButton->setChecked(false);
      }
    }
  }
};

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

  QWidget *window = new QWidget;
  QVBoxLayout *layout = new QVBoxLayout(window);

  ExclusiveButtonGroup group(window);

  QRadioButton *radioButton1 = new QRadioButton("Option 1", window);
  QRadioButton *radioButton2 = new QRadioButton("Option 2", window);
  QRadioButton *radioButton3 = new QRadioButton("Option 3", window);

  group.addButton(radioButton1);
  group.addButton(radioButton2);
  group.addButton(radioButton3);

  layout->addWidget(radioButton1);
  layout->addWidget(radioButton2);
  layout->addWidget(radioButton3);

  window->setLayout(layout);
  window->show();

  return app.exec();
}

QButtonGroup クラス

Qt 5.11 以降では、QButtonGroup クラスを使用して排他的なボタングループを作成することができます。

#include <QApplication>
#include <QRadioButton>
#include <QVBoxLayout>
#include <QButtonGroup>

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

  QWidget *window = new QWidget;
  QVBoxLayout *layout = new QVBoxLayout(window);

  QButtonGroup group;

  QRadioButton *radioButton1 = new QRadioButton("Option 1", window);
  QRadioButton *radioButton2 = new QRadioButton("Option 2", window);
  QRadioButton *radioButton3 = new QRadioButton("Option 3", window);

  group.addButton(radioButton1);
  group.addButton(radioButton2);
  group.addButton(radioButton3);

  group.setExclusive(true); // 排他性を有効にする

  layout->addWidget(radioButton1);
  layout->addWidget(radioButton2);
  layout->addWidget(radioButton3);

  window->setLayout(layout);
  window->show();

  return app.exec();
}