Qt

【C++】QtにおけるQProgressBarの使い方:基本からカスタマイズまで

QtのQProgressBarはC++でGUIアプリケーションに取り入れる進捗表示ウィジェットです。

親ウィジェットに配置し、setRangeで最小値と最大値を決め、setValueで進捗を更新することで現在の状態を示します。

シンプルな実装ながらスタイルシートを用いた外観の調整も可能で、プロジェクトの要件に合わせたカスタマイズがしやすいです。

基本設定とインスタンス生成

QProgressBarの役割

QProgressBarは、アプリケーションの進行状況を視覚的に伝えるために利用されるウィジェットです。

ユーザーに対して処理の進展状況をわかりやすく示すために、水平または垂直に配置できる進捗バーを提供します。

シンプルな表示でありながら、ユーザーの安心感を促進しますので、長時間の処理やバックグラウンドで作業が進むときに役立ちます。

インスタンス生成

オブジェクトの生成方法

QProgressBarのインスタンスは、C++で以下のように生成できます。

まずはヘッダーファイルをインクルードしてから、オブジェクトをnew演算子を用いて動的に生成します。

例えば、以下のサンプルコードを参考にしてください。

#include <QApplication>
#include <QWidget>
#include <QProgressBar>
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    QWidget window;
    // QProgressBarオブジェクトの生成
    QProgressBar *progressBar = new QProgressBar(&window);
    // ウィンドウサイズの設定
    window.resize(300, 100);
    window.show();
    return app.exec();
}
(画面にシンプルなウィンドウが表示され、その中に進捗バーが配置されているのが確認できる)

このサンプルでは、基本的なウィンドウの中にQProgressBarが生成され、ウィンドウに配置されています。

シンプルな配置方法として、new QProgressBar(&window)を用い、親ウィジェットとして&windowを渡すことがポイントです。

親ウィジェットとの連携

QProgressBarを作成する際に、親ウィジェットを渡すことで自動的にウィジェットの階層が設定され、メモリ管理やイベントの伝播がスムーズに行われます。

親ウィジェットに設定すると、ウィンドウが閉じられたときに子ウィジェットも自動的に破棄されるため、メモリリークを防ぐ効果も期待できます。

初期プロパティの設定

値の範囲設定(setRange)

進捗バーを使用する際は、進捗の最小値と最大値の範囲をsetRangeメソッドを使って設定します。

例えば、処理の開始から終了までを0から100の範囲で表したい場合は、以下のように記述します。

#include <QApplication>
#include <QWidget>
#include <QProgressBar>
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    QWidget window;
    QProgressBar *progressBar = new QProgressBar(&window);
    // 進捗バーの最小値を0、最大値を100に設定
    progressBar->setRange(0, 100);
    window.resize(300, 100);
    window.show();
    return app.exec();
}
(ウィンドウ内にある進捗バーが、0から100までの設定になっている)

このように、setRangeメソッドを使うことで、進捗バーの範囲を明確に定義できます。

初期値設定(setValue)

進捗の途中の状態を示すために、setValueメソッドを利用して任意の値を設定することができます。

例えば、50%の進行状況を示したい場合は、以下のように記述します。

#include <QApplication>
#include <QWidget>
#include <QProgressBar>
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    QWidget window;
    QProgressBar *progressBar = new QProgressBar(&window);
    progressBar->setRange(0, 100);
    // 初期値を50に設定し、50%の進行を示す
    progressBar->setValue(50);
    window.resize(300, 100);
    window.show();
    return app.exec();
}
(進捗バーの半分が進行している表示となる)

このサンプルによって、進捗バーが指定した初期値から始動する様子が確認できます。

プロパティ調整と進捗更新

最小値・最大値設定の詳細

進捗バーの動作に合わせて、最小値や最大値の調整は柔軟に行えます。

値の範囲を動的に変更する場合は、ユーザーの操作や後から発生する処理の状態に合わせて、setRangeの呼び出しを更新することが可能です。

たとえば、処理が進むにつれて最大値を動的に増やすことによって、実際の進行度をより正確に反映することができます。

進捗値更新の実装方法

更新タイミングの考慮

進捗値の更新は、進行状況の変化に応じて実施する必要があります。

バックグラウンドで重たい処理を実施する場合は、適切なタイミングでsetValueメソッドを使って更新するとスムーズに進捗状況が反映されます。

Qtのイベントループやタイマーを利用することで、進捗値の更新タイミングを調整することができます。

表示リフレッシュのポイント

進捗値が更新された後、ウィジェットの表示が自動的に再描画される仕組みが組み込まれていますが、もし描画が遅延しているように感じる場合は、repaintupdateを呼び出して明示的に表示の更新を促すことも可能です。

ユーザーにとってスムーズなビジュアルフィードバックが得られるように工夫することが大切です。

外観のカスタマイズ

スタイルシートによる設定

Qtでは、CSSに似たスタイルシート(QSS)を用いてウィジェットの外観を柔軟にカスタマイズできます。

QProgressBarの外観を変更する際は、背景色や前景色、枠線のスタイルなどを設定できます。

以下のサンプルコードは、進捗バーのデフォルトの外観を変更する例です。

#include <QApplication>
#include <QWidget>
#include <QProgressBar>
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    QWidget window;
    QProgressBar *progressBar = new QProgressBar(&window);
    progressBar->setRange(0, 100);
    progressBar->setValue(75);
    // スタイルシートを利用して進捗バーの背景色、前景色などをカスタマイズ
    progressBar->setStyleSheet(
        "QProgressBar {"
        "    background-color: #ffe6e6;"  // 背景色を薄いピンクに設定
        "    border: 1px solid #000000;"    // 枠線を黒に設定
        "    border-radius: 5px;"           // 角を丸く設定"
        "    height: 25px;"
        "}"
        "QProgressBar::chunk {"
        "    background-color: #00cc00;"    // チャンク部分の色を緑に設定
        "    width: 10px;"
        "    margin: 1px;"
        "}"
    );
    window.resize(300, 100);
    window.show();
    return app.exec();
}
(ウィンドウ内に、薄いピンクの背景と黒の枠線で囲まれた進捗バーが表示され、進行部分が緑色で示される)

このサンプルでは、QProgressBar自体とその内部の進捗部分(チャンク)に対してそれぞれスタイルを設定しています。

背景色の調整方法

スタイルシートの設定により、進捗バーの背景色は自由に変更できます。

色のコードや名前を指定することで、アプリケーション全体のデザインに合わせた背景色に変更できます。

たとえば、background-color: #ffe6e6;と記述することで、薄いピンク色に調整できます。

前景色の調整方法

進捗が進展する部分、すなわちチャンクの色は、QProgressBar::chunkセレクタを通して指定します。

好みやブランドカラーに合わせて色を変更可能です。

上記サンプルでは、background-color: #00cc00;として緑色に設定しています。

チャンク部分のカスタマイズ

チャンク部分の幅やマージンもスタイルシートで自由にカスタマイズできます。

進捗バーの滑らかさや見た目の印象を調整する上で、widthmarginのパラメータ変更は有効な手段です。

デザインの一貫性を保ちながらカスタマイズを行ってください。

サイズと向きの調整

水平表示と垂直表示の違い

QProgressBarは、水平表示と垂直表示が可能です。

水平表示は一般的に処理の進捗を示す際に用いられ、垂直表示は空間の使い方の工夫として利用されることが多くなります。

どちらもsetOrientationメソッドを使用して設定することができます。

たとえば、垂直表示に変更するサンプルコードは以下の通りです。

#include <QApplication>
#include <QWidget>
#include <QProgressBar>
#include <Qt>
// Qt::Verticalを利用して垂直表示に設定
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    QWidget window;
    QProgressBar *verticalProgressBar = new QProgressBar(&window);
    verticalProgressBar->setOrientation(Qt::Vertical);
    verticalProgressBar->setRange(0, 100);
    verticalProgressBar->setValue(60);
    window.resize(100, 300);
    window.show();
    return app.exec();
}
(ウィンドウ内に垂直方向に進捗が表示され、60%の進行状況が見て取れる)

サイズ調整のポイント

進捗バーのサイズは、ウィジェット全体のデザインやレイアウトに合わせて調整します。

ウィンドウのレイアウトマネージャを活用するか、setFixedSizeresizeメソッドを使用してサイズを明示的に設定することも可能です。

サイズが小さすぎる場合は情報が伝わりにくくなるため、調整する際は視認性を最重要視して検討してください。

シグナルとスロットによる連携

イベント連動の基本

Qtのシグナルとスロット機構を利用すると、進捗の状態変化に合わせたイベント処理が簡単に実装できます。

たとえば、バックグラウンドの処理完了時に進捗バーの値を更新する場合、シグナルを発信し、スロットでその更新を受け取ります。

状態変化イベントの処理

進捗状況の更新が必要なタイミングでは、処理結果に基づくシグナルが発信されます。

シグナルが発信されると、関連付けられたスロットが実行され、進捗バーのsetValueメソッドが適切に呼び出されます。

この仕組みは、非同期処理の中でも有効に働き、ユーザーにリアルタイムのフィードバックを提供できます。

シグナルの発信と受信の手法

基本的なシグナルとスロットの連携方法としては、QObjectのconnectメソッドを利用します。

下記サンプルコードは、シグナル発信と受信の簡単な例です。

#include <QApplication>
#include <QWidget>
#include <QProgressBar>
#include <QTimer>
#include <QObject>
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    QWidget window;
    QProgressBar *progressBar = new QProgressBar(&window);
    progressBar->setRange(0, 100);
    progressBar->setValue(0);
    // QTimerを用いて進捗値を順次更新する例
    QTimer *timer = new QTimer(&window);
    QObject::connect(timer, &QTimer::timeout, [&](){
        int currentValue = progressBar->value();
        // 進捗が100未満の場合、10ずつ加算
        if(currentValue < 100){
            progressBar->setValue(currentValue + 10);
        }
    });
    timer->start(500);  // 500ミリ秒ごとに更新
    window.resize(300, 100);
    window.show();
    return app.exec();
}
(ウィンドウ内の進捗バーが0から100まで順次10ずつ更新され、リアルタイムに進捗状況が変化する)

この例では、QTimerを使用して500ミリ秒ごとに進捗値が更新される仕組みを実装し、シグナルとスロットによってイベントが連動して処理される様子を確認できます。

他ウィジェットとの同期連携

リアルタイム更新の工夫

進捗バーは、他のウィジェットとも連携が可能です。

たとえば、処理内容を示すラベルと同期させる場合、ラベルのテキストをsetTextで更新し、進捗の変化を同時に反映させることができます。

ウィジェット間で同じシグナルを共有することで、一括で状態を変更する仕組みを取り入れると、ユーザーにとって分かりやすいインターフェースが実現できます。

下記は、ラベルと進捗バーを連動させる簡単な例です。

#include <QApplication>
#include <QWidget>
#include <QProgressBar>
#include <QLabel>
#include <QVBoxLayout>
#include <QTimer>
#include <QObject>
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    QWidget window;
    QProgressBar *progressBar = new QProgressBar(&window);
    progressBar->setRange(0, 100);
    progressBar->setValue(0);
    QLabel *statusLabel = new QLabel("進捗:0%", &window);
    QVBoxLayout *layout = new QVBoxLayout(&window);
    layout->addWidget(progressBar);
    layout->addWidget(statusLabel);
    // QTimerで進捗状況を更新し、ラベルと連動させる
    QTimer *timer = new QTimer(&window);
    QObject::connect(timer, &QTimer::timeout, [&](){
        int currentValue = progressBar->value();
        if(currentValue < 100){
            int nextValue = currentValue + 5;
            progressBar->setValue(nextValue);
            statusLabel->setText(QString("進捗:%1%").arg(nextValue));
        }
    });
    timer->start(300);
    window.resize(300,150);
    window.show();
    return app.exec();
}
(ウィンドウ内に進捗バーと進捗状況を示すラベルが表示され、進捗バーとラベルのテキストが同時に更新される)

このコードでは、進捗バーとラベルの連携がしっかりと実現され、ユーザーに対して処理の進捗が視覚的かつテキスト上でも把握できる工夫が導入されています。

拡張性と応用例

継承を用いたカスタマイズ

サブクラス化の手法

既存のQProgressBarを拡張して独自の動作や外観を加えたい場合は、継承を利用してサブクラスを作成する手法が有効です。

サブクラスを作成することで、標準の動作に加えて、新たなメソッドを追加したり、シグナルやスロットを独自に実装することができます。

下記のサンプルコードは、シンプルなサブクラスの例です。

#include <QApplication>
#include <QWidget>
#include <QProgressBar>

// CustomProgressBarはQProgressBarを継承して独自の動作を実装する例
class CustomProgressBar : public QProgressBar
{
public:
    CustomProgressBar(QWidget *parent = nullptr) : QProgressBar(parent) {
        // コンストラクタ内で必要な初期化処理を実施
    }
    // 独自のメソッドを追加して表示の更新タイミングを調整する
    void updateProgress(int value) {
        setValue(value);
    }
};

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    QWidget window;
    CustomProgressBar *customBar = new CustomProgressBar(&window);
    customBar->setRange(0, 100);
    customBar->setValue(30);
    window.resize(300, 100);
    window.show();
    return app.exec();
}
(ウィンドウ内に標準のQProgressBarと同等の機能を持ったカスタム進捗バーが表示され、初期値が30となる)

拡張のポイント

サブクラス化によって、既存の機能に加え、進捗のアニメーションやクリックなどのユーザーインタラクションに応じた動作を追加することができます。

これにより、柔軟かつ独自性の高いウィジェットとして利用できる拡張が可能になります。

複数QProgressBarの連携利用

一括制御の考慮点

複数の進捗バーを同時に管理する場合、進捗値の同期や一括更新が必要となることがよくあります。

各バーに対して個別に設定するのではなく、共通のシグナルを介して一括制御する仕組みを導入することで、管理が容易になり、ユーザーにも統一感のある表示が提供できます。

統一デザインの保持方法

複数の進捗バーを利用する際、スタイルシートやサイズの設定を揃えることにより、統一感のあるデザインが実現できます。

共通のスタイルシートを利用して各ウィジェットに適用するか、レイアウトマネージャを活用して自動的にサイズや配置を整えると、全体の見た目に一貫性を持たせることができます。

まとめ

各トピックで紹介した内容を活用することで、QProgressBarを柔軟にカスタマイズしながら活用できる環境が整います。

基本的な初期設定から始まり、プロパティの調整、外観のカスタマイズ、シグナルとスロットによるイベント連携、さらなる拡張性の確保まで、さまざまな観点からの工夫が取り入れられています。

ユーザーにとって分かりやすく操作しやすい進捗表示を実現するため、これらのポイントを参考にしてみてください。

関連記事

Back to top button
目次へ