Qt (C++/Python) QSpinBoxのsingleStep設定と活用方法:実例コード付き

2025-05-31

「QSpinBox::singleStep」は、QtフレームワークにおけるQSpinBoxクラス(数値を増減させるためのウィジェット)の重要なプロパティの一つです。これは、スピンボックスの値を1回だけ増減させる際の増減量を定義します。

具体的には、以下の状況でこのsingleStepの値が影響を与えます。

  • stepUp()とstepDown()メソッドの呼び出し
    QSpinBoxオブジェクトのプログラム上からstepUp()メソッドやstepDown()メソッドを呼び出した場合にも、singleStepの値に基づいて値が変更されます。
  • キーボードの上下キーの操作
    スピンボックスにフォーカスがある状態で、キーボードの上向きキー(↑)を押すと現在値にsingleStepが加算され、下向きキー(↓)を押すと減算されます。
  • 上下の矢印ボタンのクリック
    スピンボックスの左右、または上下に配置された矢印ボタンを1回クリックした際に、現在値にsingleStepの値が加算または減算されます。

デフォルトの値

singleStepのデフォルト値は1です。つまり、特に設定しない限り、矢印ボタンのクリックやキーボード操作で値は1ずつ増減します。

設定方法

singleStepの値は、以下の方法で設定できます。

  • プログラムコード
    C++またはPythonなどのプログラミング言語で、QSpinBoxオブジェクトのsetSingleStep()メソッドを使用して値を設定できます。

    C++の例

    QSpinBox *spinBox = new QSpinBox(this);
    spinBox->setSingleStep(5); // 1回の増減量を5に設定
    

    Pythonの例 (PyQt/PySide)

    spin_box = QSpinBox(self)
    spin_box.setSingleStep(5)  # 1回の増減量を5に設定
    
  • Qt Designer
    Qt DesignerなどのGUIデザインツールを使用している場合、プロパティエディタでsingleStepの値を直接設定できます。

使用例

例えば、時間(分)を選択するスピンボックスを作成する場合、1分単位で増減させるのが自然です。この場合、singleStepのデフォルト値である1のままで問題ありません。

しかし、例えば、ある設定値を5単位で調整したい場合などには、setSingleStep(5)のように設定することで、より効率的な操作を提供できます。



一般的なエラーとトラブルシューティング

QSpinBox::singleStep自体が直接エラーを引き起こすことは比較的少ないですが、その設定や使い方に関連して予期せぬ動作やユーザーからの問い合わせが発生することがあります。以下に、よくあるケースと対処法を挙げます。

意図しない増減量

  • トラブルシューティング
    • 設定値の確認
      Qt Designerやプログラムコードで、singleStep()メソッドやプロパティの値を確認してください。
    • 初期化処理の確認
      スピンボックスの初期化時に、意図したsingleStepの値が正しく設定されているかを確認してください。
    • 値の範囲との関連
      minimum()maximum()で設定された値の範囲に対して、singleStepの値が適切かどうかを検討してください。極端に大きなsingleStepは、範囲内の値を飛び越えてしまう可能性があります。
  • 原因
    singleStepに意図しない値が設定されている。例えば、誤って大きな値を設定してしまい、クリックやキー操作で値が大きく変動してしまう。

増減量の単位の誤解

  • トラブルシューティング
    • QDoubleSpinBoxの検討
      小数点以下の値を扱いたい場合は、QSpinBoxではなくQDoubleSpinBoxの使用を検討してください。QDoubleSpinBoxにはsingleStep()double型の値を設定できます。
    • ユーザーへの説明
      アプリケーションのヘルプやユーザーインターフェース上で、増減量の単位を明確に説明することが重要です。
  • 原因
    ユーザーがsingleStepの単位を誤解している。例えば、「0.1刻みで増減させたい」と考えているのに、整数値のsingleStepを設定している。

シグナルとスロットの連携ミス

  • トラブルシューティング
    • シグナルの発生タイミングの確認
      valueChanged()シグナルは、値が変更されるたびに発行されます。singleStepを変更した場合、その後の操作で値が変化する際にシグナルが発行されることを理解しておきましょう。
    • スロット側の処理の確認
      スロット関数内で、受け取った値がsingleStepの設定と矛盾していないか、意図した処理が行われているかを確認してください。
  • 原因
    valueChanged()などのシグナルとスロットを連携させている場合に、singleStepの変更によって発生する値の変化が、期待通りに処理されない。

カスタムな増減処理との競合

  • トラブルシューティング
    • カスタム処理の確認
      カスタムな増減処理がsingleStepの値を無視していないか、または意図しない影響を与えていないかを確認してください。
    • 意図の明確化
      カスタム処理とsingleStepのどちらを優先するのか、設計を明確にする必要があります。
  • 原因
    stepUp()stepDown()メソッドをオーバーライドしたり、独自のロジックで値の増減を制御したりしている場合に、singleStepの設定が期待通りに機能しない。

UIのフリーズやパフォーマンスの問題 (稀なケース)

  • トラブルシューティング
    • 値の範囲とsingleStepの再検討
      極端な設定が本当に必要かどうかを検討し、より適切な値に調整してください。
    • 処理の最適化
      valueChanged()シグナルに接続されたスロット関数の処理が重くないかを確認し、必要であれば最適化を検討してください。
  • 原因
    singleStepの値が極端に小さい、または非常に大きな値の範囲で使用している場合に、連続的な増減操作によってUIがフリーズしたり、パフォーマンスが低下したりする可能性はごく稀にあります。
  • Qtのドキュメント参照
    QSpinBoxクラスや関連するメソッドの公式ドキュメントを再度確認し、理解を深めてください。
  • 最小限のコードでの再現
    問題を特定するために、関係する部分だけを抽出した最小限のコードで問題を再現させてみてください。
  • ログ出力
    重要な処理や値の変化をログに出力するようにしておくと、問題発生時の追跡に役立ちます。
  • デバッグ
    Qtのデバッガを使用して、プログラムの実行中にsingleStep()の値やスピンボックスの値の変化を監視してください。


基本的な singleStep の設定 (C++)

#include <QApplication>
#include <QMainWindow>
#include <QSpinBox>
#include <QVBoxLayout>
#include <QWidget>
#include <QLabel>

int main(int argc, char *argv[]) {
    QApplication a(argc, argv);
    QMainWindow window;
    QWidget *centralWidget = new QWidget(&window);
    QVBoxLayout *layout = new QVBoxLayout(centralWidget);

    QLabel *label = new QLabel("現在の値:");
    QSpinBox *spinBox = new QSpinBox();
    QLabel *stepLabel = new QLabel("singleStep: ");
    QSpinBox *stepSpinBox = new QSpinBox(); // singleStep を設定するためのスピンボックス

    // singleStep の初期値を設定
    spinBox->setSingleStep(1);
    stepSpinBox->setValue(spinBox->singleStep()); // 初期値を表示

    // stepSpinBox の値が変更されたら、spinBox の singleStep を更新
    QObject::connect(stepSpinBox, QOverload<int>::of(&QSpinBox::valueChanged),
                     [spinBox](int newStep) {
                         spinBox->setSingleStep(newStep);
                     });

    layout->addWidget(label);
    layout->addWidget(spinBox);
    layout->addWidget(stepLabel);
    layout->addWidget(stepSpinBox);
    centralWidget->setLayout(layout);
    window.setCentralWidget(centralWidget);
    window.setWindowTitle("QSpinBox singleStep Example (C++)");
    window.show();

    return a.exec();
}

解説 (C++)

  1. QSpinBox *spinBox = new QSpinBox();: メインの数値を操作する QSpinBox を作成します。
  2. spinBox->setSingleStep(1);: singleStep の初期値を 1 に設定します。
  3. QSpinBox *stepSpinBox = new QSpinBox();: singleStep の値を変更するための別の QSpinBox を作成します。
  4. QObject::connect(...): stepSpinBox の値が変更されると (valueChanged シグナル)、ラムダ式を使ってメインの spinBoxsingleStep を新しい値 (newStep) に更新します。
  5. これにより、ユーザーは stepSpinBox を操作することで、メインの spinBox の増減量を動的に変更できます。

基本的な singleStep の設定 (Python - PyQt/PySide)

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QLabel, QSpinBox
# from PySide6.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QLabel, QSpinBox # PySide を使用する場合

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        central_widget = QWidget()
        layout = QVBoxLayout(central_widget)

        self.label = QLabel("現在の値:")
        self.spin_box = QSpinBox()
        self.step_label = QLabel("singleStep: ")
        self.step_spin_box = QSpinBox()

        # singleStep の初期値を設定
        self.spin_box.setSingleStep(1)
        self.step_spin_box.setValue(self.spin_box.singleStep()) # 初期値を表示

        # step_spin_box の値が変更されたら、spin_box の singleStep を更新
        self.step_spin_box.valueChanged.connect(self.update_single_step)

        layout.addWidget(self.label)
        layout.addWidget(self.spin_box)
        layout.addWidget(self.step_label)
        layout.addWidget(self.step_spin_box)
        central_widget.setLayout(layout)
        self.setCentralWidget(central_widget)
        self.setWindowTitle("QSpinBox singleStep Example (Python)")

    def update_single_step(self, new_step):
        self.spin_box.setSingleStep(new_step)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    main_window = MainWindow()
    main_window.show()
    sys.exit(app.exec_())

解説 (Python - PyQt/PySide)

  1. self.spin_box = QSpinBox(): メインの数値を操作する QSpinBox を作成します。
  2. self.spin_box.setSingleStep(1): singleStep の初期値を 1 に設定します。
  3. self.step_spin_box = QSpinBox(): singleStep の値を変更するための別の QSpinBox を作成します。
  4. self.step_spin_box.valueChanged.connect(self.update_single_step): step_spin_box の値が変更されると (valueChanged シグナル)、update_single_step メソッドが呼び出されます。
  5. update_single_step(self, new_step) メソッド内で、メインの self.spin_boxsingleStep を新しい値 (new_step) に設定します。

singleStep を小数値で設定する場合 (QDoubleSpinBox)

QSpinBox は整数の値を扱いますが、小数値を扱いたい場合は QDoubleSpinBox を使用します。QDoubleSpinBoxsetSingleStep() メソッドは double 型の引数を取り、小数値の増減量を設定できます。

例 (C++)

#include <QApplication>
#include <QMainWindow>
#include <QDoubleSpinBox>
#include <QVBoxLayout>
#include <QWidget>
#include <QLabel>

int main(int argc, char *argv[]) {
    QApplication a(argc, argv);
    QMainWindow window;
    QWidget *centralWidget = new QWidget(&window);
    QVBoxLayout *layout = new QVBoxLayout(centralWidget);

    QLabel *label = new QLabel("現在の値:");
    QDoubleSpinBox *doubleSpinBox = new QDoubleSpinBox();
    QLabel *stepLabel = new QLabel("singleStep: ");
    QDoubleSpinBox *stepDoubleSpinBox = new QDoubleSpinBox();

    // singleStep に小数値を設定
    doubleSpinBox->setSingleStep(0.1);
    stepDoubleSpinBox->setValue(doubleSpinBox->singleStep());

    QObject::connect(stepDoubleSpinBox, QOverload<double>::of(&QDoubleSpinBox::valueChanged),
                     [doubleSpinBox](double newStep) {
                         doubleSpinBox->setSingleStep(newStep);
                     });

    layout->addWidget(label);
    layout->addWidget(doubleSpinBox);
    layout->addWidget(stepLabel);
    layout->addWidget(stepDoubleSpinBox);
    centralWidget->setLayout(layout);
    window.setCentralWidget(centralWidget);
    window.setWindowTitle("QDoubleSpinBox singleStep Example (C++)");
    window.show();

    return a.exec();
}
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QLabel
from PyQt5.QtWidgets import QDoubleSpinBox
# from PySide6.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QLabel
# from PySide6.QtWidgets import QDoubleSpinBox # PySide を使用する場合

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        central_widget = QWidget()
        layout = QVBoxLayout(central_widget)

        self.label = QLabel("現在の値:")
        self.double_spin_box = QDoubleSpinBox()
        self.step_label = QLabel("singleStep: ")
        self.step_double_spin_box = QDoubleSpinBox()

        # singleStep に小数値を設定
        self.double_spin_box.setSingleStep(0.1)
        self.step_double_spin_box.setValue(self.double_spin_box.singleStep())

        self.step_double_spin_box.valueChanged.connect(self.update_single_step)

        layout.addWidget(self.label)
        layout.addWidget(self.double_spin_box)
        layout.addWidget(self.step_label)
        layout.addWidget(self.step_double_spin_box)
        central_widget.setLayout(layout)
        self.setCentralWidget(central_widget)
        self.setWindowTitle("QDoubleSpinBox singleStep Example (Python)")

    def update_single_step(self, new_step):
        self.double_spin_box.setSingleStep(new_step)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    main_window = MainWindow()
    main_window.show()
    sys.exit(app.exec_())


シグナルとスロットによる間接的な制御

直接 setSingleStep() を呼び出すのではなく、他のウィジェットの状態変化に応じて singleStep を間接的に制御する方法です。

例 (C++)

#include <QApplication>
#include <QMainWindow>
#include <QSpinBox>
#include <QSlider>
#include <QVBoxLayout>
#include <QWidget>
#include <QLabel>

int main(int argc, char *argv[]) {
    QApplication a(argc, argv);
    QMainWindow window;
    QWidget *centralWidget = new QWidget(&window);
    QVBoxLayout *layout = new QVBoxLayout(centralWidget);

    QLabel *label = new QLabel("値:");
    QSpinBox *spinBox = new QSpinBox();
    QLabel *sliderLabel = new QLabel("増減のステップ:");
    QSlider *stepSlider = new QSlider(Qt::Horizontal);
    stepSlider->setMinimum(1);
    stepSlider->setMaximum(10);
    stepSlider->setValue(1); // 初期値

    spinBox->setSingleStep(stepSlider->value()); // 初期値をスライダーの値に合わせる

    QObject::connect(stepSlider, &QSlider::valueChanged,
                     [spinBox](int newStep) {
                         spinBox->setSingleStep(newStep);
                     });

    layout->addWidget(label);
    layout->addWidget(spinBox);
    layout->addWidget(sliderLabel);
    layout->addWidget(stepSlider);
    centralWidget->setLayout(layout);
    window.setCentralWidget(centralWidget);
    window.setWindowTitle("QSpinBox singleStep Alternative (C++)");
    window.show();

    return a.exec();
}

例 (Python - PyQt/PySide)

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QLabel, QSpinBox, QSlider
from PyQt5.QtCore import Qt
# from PySide6.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QLabel, QSpinBox, QSlider
# from PySide6.QtCore import Qt # PySide を使用する場合

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        central_widget = QWidget()
        layout = QVBoxLayout(central_widget)

        self.label = QLabel("値:")
        self.spin_box = QSpinBox()
        self.slider_label = QLabel("増減のステップ:")
        self.step_slider = QSlider(Qt.Horizontal)
        self.step_slider.setMinimum(1)
        self.step_slider.setMaximum(10)
        self.step_slider.setValue(1) # 初期値

        self.spin_box.setSingleStep(self.step_slider.value()) # 初期値をスライダーの値に合わせる

        self.step_slider.valueChanged.connect(self.update_single_step)

        layout.addWidget(self.label)
        layout.addWidget(self.spin_box)
        layout.addWidget(self.slider_label)
        layout.addWidget(self.step_slider)
        central_widget.setLayout(layout)
        self.setCentralWidget(central_widget)
        self.setWindowTitle("QSpinBox singleStep Alternative (Python)")

    def update_single_step(self, new_step):
        self.spin_box.setSingleStep(new_step)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    main_window = MainWindow()
    main_window.show()
    sys.exit(app.exec_())

解説

この例では、QSlider の値の変化に応じて QSpinBoxsingleStep を更新しています。スライダーを操作することで、スピンボックスの増減量をリアルタイムに変更できます。このように、他のウィジェットの状態に基づいて singleStep を動的に制御することができます。

カスタムスロットによる制御

特定のイベントが発生した際に、カスタムのスロット関数を呼び出し、その中で singleStep の値を変更する方法です。

例 (C++)

#include <QApplication>
#include <QMainWindow>
#include <QSpinBox>
#include <QPushButton>
#include <QVBoxLayout>
#include <QWidget>
#include <QLabel>

class MainWindow : public QMainWindow {
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr) : QMainWindow(parent) {
        QWidget *centralWidget = new QWidget(this);
        QVBoxLayout *layout = new QVBoxLayout(centralWidget);

        valueLabel = new QLabel("値:");
        spinBox = new QSpinBox();
        stepLabel = new QLabel("singleStep: 1");
        increaseStepButton = new QPushButton("ステップを増やす");
        decreaseStepButton = new QPushButton("ステップを減らす");

        spinBox->setSingleStep(1);
        currentStep = 1;

        connect(increaseStepButton, &QPushButton::clicked, this, &MainWindow::increaseSingleStep);
        connect(decreaseStepButton, &QPushButton::clicked, this, &MainWindow::decreaseSingleStep);

        layout->addWidget(valueLabel);
        layout->addWidget(spinBox);
        layout->addWidget(stepLabel);
        layout->addWidget(increaseStepButton);
        layout->addWidget(decreaseStepButton);
        centralWidget->setLayout(layout);
        setCentralWidget(centralWidget);
        setWindowTitle("QSpinBox Custom Step Control (C++)");
    }

private slots:
    void increaseSingleStep() {
        currentStep++;
        spinBox->setSingleStep(currentStep);
        stepLabel->setText(QString("singleStep: %1").arg(currentStep));
    }

    void decreaseSingleStep() {
        if (currentStep > 1) {
            currentStep--;
            spinBox->setSingleStep(currentStep);
            stepLabel->setText(QString("singleStep: %1").arg(currentStep));
        }
    }

private:
    QSpinBox *spinBox;
    QLabel *valueLabel;
    QLabel *stepLabel;
    QPushButton *increaseStepButton;
    QPushButton *decreaseStepButton;
    int currentStep;
};

#include "main.moc" // moc ファイルのインクルード

int main(int argc, char *argv[]) {
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

例 (Python - PyQt/PySide)

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QLabel, QSpinBox, QPushButton

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        central_widget = QWidget()
        layout = QVBoxLayout(central_widget)

        self.value_label = QLabel("値:")
        self.spin_box = QSpinBox()
        self.step_label = QLabel("singleStep: 1")
        self.increase_step_button = QPushButton("ステップを増やす")
        self.decrease_step_button = QPushButton("ステップを減らす")

        self.spin_box.setSingleStep(1)
        self.current_step = 1

        self.increase_step_button.clicked.connect(self.increase_single_step)
        self.decrease_step_button.clicked.connect(self.decrease_single_step)

        layout.addWidget(self.value_label)
        layout.addWidget(self.spin_box)
        layout.addWidget(self.step_label)
        layout.addWidget(self.increase_step_button)
        layout.addWidget(self.decrease_step_button)
        central_widget.setLayout(layout)
        self.setCentralWidget(central_widget)
        self.setWindowTitle("QSpinBox Custom Step Control (Python)")

    def increase_single_step(self):
        self.current_step += 1
        self.spin_box.setSingleStep(self.current_step)
        self.step_label.setText(f"singleStep: {self.current_step}")

    def decrease_single_step(self):
        if self.current_step > 1:
            self.current_step -= 1
            self.spin_box.setSingleStep(self.current_step)
            self.step_label.setText(f"singleStep: {self.current_step}")

if __name__ == '__main__':
    app = QApplication(sys.argv)
    main_window = MainWindow()
    main_window.show()
    sys.exit(app.exec_())

解説

この例では、2つのボタン (increaseStepButton, decreaseStepButton) を用意し、クリックされるたびにカスタムのスロット関数 (increaseSingleStep, decreaseSingleStep) が呼び出されます。これらのスロット関数内で singleStep の値を増減させ、ラベル (stepLabel) に現在の singleStep の値を表示しています。

派生クラスでのカスタマイズ

QSpinBox を継承した独自のクラスを作成し、stepBy() などの仮想関数をオーバーライドすることで、増減のロジックを完全にカスタマイズする方法も考えられます。この方法はより高度な制御が必要な場合に有効です。

例 (C++)

#include <QApplication>
#include <QMainWindow>
#include <QSpinBox>
#include <QVBoxLayout>
#include <QWidget>
#include <QLabel>
#include <QKeyEvent>

class CustomSpinBox : public QSpinBox {
public:
    CustomSpinBox(QWidget *parent = nullptr) : QSpinBox(parent) {}

protected:
    void stepBy(int steps) override {
        // steps に現在の singleStep を掛けた値で増減させる
        QSpinBox::stepBy(steps * singleStep());
    }

    void keyPressEvent(QKeyEvent *event) override {
        if (event->key() == Qt::Key_PageUp) {
            QSpinBox::stepBy(5 * singleStep()); // PageUp で 5 ステップ分増やす
        } else if (event->key() == Qt::Key_PageDown) {
            QSpinBox::stepBy(-5 * singleStep()); // PageDown で 5 ステップ分減らす
        } else {
            QSpinBox::keyPressEvent(event); // その他のキーイベントはデフォルトの処理に任せる
        }
    }
};

int main(int argc, char *argv[]) {
    QApplication a(argc, argv);
    QMainWindow window;
    QWidget *centralWidget = new QWidget(&window);
    QVBoxLayout *layout = new QVBoxLayout(centralWidget);

    QLabel *label = new QLabel("値:");
    CustomSpinBox *spinBox = new CustomSpinBox();
    spinBox->setSingleStep(2); // singleStep を 2 に設定

    layout->addWidget(label);
    layout->addWidget(spinBox);
    centralWidget->setLayout(layout);
    window.setCentralWidget(centralWidget);
    window.setWindowTitle("Custom QSpinBox Example (C++)");
    window.show();

    return a.exec();
}

例 (Python - PyQt/PySide)

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QLabel, QSpinBox
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QKeyEvent
# from PySide6.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QLabel, QSpinBox
# from PySide6.QtCore import Qt
# from PySide6.QtGui import QKeyEvent # PySide を使用する場合

class CustomSpinBox(QSpinBox):
    def __init__(self, parent=None):
        super().__init__(parent)

    def stepBy(self, steps: int):
        super().stepBy(steps * self.singleStep())

    def keyPressEvent(self, event: QKeyEvent):
        if event.key() == Qt.Key_PageUp:
            super().stepBy(5 * self.singleStep())
        elif event.key() == Qt.Key_PageDown:
            super().stepBy(-5 * self.singleStep())
        else:
            super().keyPressEvent(event)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = QMainWindow()
    central_widget = QWidget()
    layout = QVBoxLayout(central_widget)

    label = QLabel("値:")
    spin_box = CustomSpinBox()
    spin_box.setSingleStep(2) # singleStep を 2 に設定

    layout.addWidget(label)
    layout.addWidget(spin_box)
    central_widget.setLayout(layout)
    window.setCentralWidget(central_widget)
    window.setWindowTitle("Custom QSpinBox Example (Python)")
    window.show()
    sys.exit(app.exec_())

解説

この例では、CustomSpinBox クラスが QSpinBox を継承し、stepBy() メソッドと keyPressEvent() メソッドをオーバーライドしています。

  • keyPressEvent(): PageUp キーと PageDown キーが押された際に、singleStep の 5 倍のステップ数で値を増減させるようにカスタム処理を追加しています。
  • stepBy(): デフォルトの増減処理を、指定されたステップ数に現在の singleStep を掛けた値で行うように変更しています。