【初心者向け】Qt GUIプログラミング:QIntValidatorで入力値をバリデーションする方法


Qt GUIにおけるQIntValidator::validate()関数は、入力された文字列が有効な整数かどうかを検証するために使用されます。この関数は、入力文字列と検証範囲をパラメータとして受け取り、以下の3つの状態を返します。

  • Invalid
    入力文字列が有効な整数ではない場合
  • Intermediate
    入力文字列が有効な整数の接頭辞であり、検証範囲内に収まる可能性がある場合
  • Acceptable
    入力文字列が有効な整数であり、検証範囲内に収まっている場合

詳細

QIntValidator::validate()関数は、以下のアルゴリズムを使用して入力文字列を検証します。

  1. 入力文字列が空の場合、Acceptableを返します。
  2. 入力文字列の先頭文字がマイナス記号('-')以外に、数字以外の文字である場合、Invalidを返します。
  3. 入力文字列がマイナス記号を含んでいる場合、マイナス記号が1つだけであることを確認します。
  4. 入力文字列を数値に変換し、変換に成功した場合、以下の条件を満たすかどうかを確認します。
    • 整数値が検証範囲の最小値以上であること
    • 整数値が検証範囲の最大値以下であること
  5. 上記の条件を満たす場合、Acceptableを返します。
  6. 上記の条件を満たさない場合、Intermediateを返します。

以下のコードは、QIntValidator::validate()関数を使用して、入力文字列が-100から100までの範囲の整数かどうかを検証する例です。

QIntValidator validator(-100, 100);

QString input = "50";
int pos = 0;

QValidator::State state = validator.validate(input, pos);

if (state == QValidator::Acceptable) {
    // 入力文字列は有効な整数であり、検証範囲内に収まっている
} else if (state == QValidator::Intermediate) {
    // 入力文字列は有効な整数の接頭辞であり、検証範囲内に収まる可能性がある
} else {
    // 入力文字列は有効な整数ではない
}

QIntValidator::validate()関数は、入力文字列の一部のみを検証することもできます。これは、posパラメータを使用して行います。posパラメータは、検証された文字列の最後の文字の位置を格納します。

QString input = "-123";
int pos = 0;

QValidator::State state = validator.validate(input, pos);

if (state == QValidator::Acceptable) {
    // 入力文字列は有効な整数であり、検証範囲内に収まっている
} else if (state == QValidator::Intermediate) {
    // 入力文字列は有効な整数の接頭辞であり、検証範囲内に収まる可能性がある
} else {
    // 入力文字列は有効な整数ではない
}

qDebug() << "pos:" << pos; // posは3になる


整数入力のみ許可するLineEdit

#include <QtWidgets/QApplication>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QVBoxLayout>

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

    QLineEdit *lineEdit = new QLineEdit;
    QIntValidator *validator = new QIntValidator(-100, 100);
    lineEdit->setValidator(validator);

    QVBoxLayout *layout = new QVBoxLayout;
    layout->addWidget(lineEdit);

    QWidget *widget = new QWidget;
    widget->setLayout(layout);
    widget->show();

    return app.exec();
}

このコードを実行すると、以下のようになります。

最小値と最大値を指定した範囲内の整数入力のみ許可するLineEdit

この例では、QIntValidatorを使用して、QLineEditに入力できる値を最小値と最大値を指定した範囲内の整数のみ許可します。

#include <QtWidgets/QApplication>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QVBoxLayout>

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

    QLineEdit *lineEdit = new QLineEdit;
    QIntValidator *validator = new QIntValidator(10, 20);
    lineEdit->setValidator(validator);

    QVBoxLayout *layout = new QVBoxLayout;
    layout->addWidget(lineEdit);

    QWidget *widget = new QWidget;
    widget->setLayout(layout);
    widget->show();

    return app.exec();
}

この例では、QIntValidatorを使用して、QLineEditに入力できる値を正の整数のみ許可します。

#include <QtWidgets/QApplication>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QVBoxLayout>

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

    QLineEdit *lineEdit = new QLineEdit;
    QIntValidator *validator = new QIntValidator(0, std::numeric_limits<int>::max());
    validator->setBottom(0);
    lineEdit->setValidator(validator);

    QVBoxLayout *layout = new QVBoxLayout;
    layout->addWidget(lineEdit);

    QWidget *widget = new QWidget;
    widget->setLayout(layout);
    widget->show();

    return app.exec();
}

ユーザーは、QLineEditに正の整数のみを入力することができます。負の値を入力しようとすると、入力値は拒否されます。



代替方法

以下に、QIntValidator::validate()の代替方法のいくつかを紹介します。

  • 正規表現を使用する
    正規表現を使用して、入力された文字列が整数かどうかを検証することができます。これは、QRegularExpressionクラスを使用して行うことができます。
QRegularExpression regex("\\d+"); // 数字のみを許可する正規表現

QString input = "50";

if (regex.match(input).hasMatch()) {
    // 入力文字列は有効な整数である
} else {
    // 入力文字列は有効な整数ではない
}
  • std::stoi()関数を使用する
    std::stoi()関数は、文字列を整数に変換するために使用することができます。この関数は、変換に失敗した場合に例外をスローするため、エラー処理が必要となります。
#include <stdexcept>

QString input = "50";

try {
    int value = std::stoi(input.toStdString());
    // 入力文字列は有効な整数である
} catch (const std::exception& e) {
    // 入力文字列は有効な整数ではない
}
  • QLocaleクラスを使用する
    QLocaleクラスは、ロケール固有の書式設定を使用して文字列を数値に変換するために使用することができます。
QLocale locale(QLocale::system());
QString input = "50";

bool ok;
int value = locale.toInt(input, &ok);

if (ok) {
    // 入力文字列は有効な整数である
} else {
    // 入力文字列は有効な整数ではない
}

それぞれの方法の利点と欠点

それぞれの方法には、それぞれ利点と欠点があります。

  • QLocaleクラス
    • 利点
      ロケール固有の書式設定に対応できる
    • 欠点
      他の方法よりも複雑
  • std::stoi()関数
    • 利点
      シンプルでわかりやすい
    • 欠点
      エラー処理が必要
  • 正規表現
    • 利点
      柔軟性が高く、さまざまな形式の整数に対応できる
    • 欠点
      複雑でわかりにくい場合がある