ホーム

OFF-SOFT.net

OFF-SOFT.net

ウェブやソフトウェアに関するサポート&情報サイトです。サイト構築からソフトウェアの作成、利用まであなたの助けになるかも・・・・しれません。たぶん・・。

Qt(B4) Qt でMarquee表示

公開日| 2009年08月27日 | コメントはまだありません。
概要 :
 今回は、Qtのプログレスバーにmarquee表示を行う方法を簡単に解説します。
marqueeとは、WindowsXP以降からの起動画面で、プログレスバーが、増えていくのでなく、流れるような表示を行い、現在、処理中を表示するものです。

 このmarquee(宣伝表示)とは、色々な呼称があります。
indeterminate(どれくらい実行中かわからないけど実効中),barber-pole(床屋さんのポール), spinning bar(ぐるぐるスピンするバー)などです。
(Web上では、barber-poleがメジャーなようですが、ここでは、marqueeで統一しておきます。()内は日本語の直訳です。なんとなく理解してもらえれば良いかと思いましたので記述してみました。)

WindowsのAPIで対応されるようになったのは、それほど古いことではありません。

 今回は、Qtで提供されているサンプルを使って、そのmarquee表示を行ってみます。



早速、サンプルを使って表示してみましょう
ここで使用するサンプルは、プログレスバーのサンプルです。
通常、以下のディレクトリにあります。
%Qtインストール先ディレクトリ%\qt\examples\qtconcurrent\progressdialog
以下は、そのmain.cppです。
[main.cpp]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
using namespace QtConcurrent;
 
const int iterations = 20;
 
void spin(int &iteration)
{
    const int work = 1000 * 1000 * 40;
    volatile int v = 0;
    for (int j = 0; j < work; ++j)
        ++v;
 
    qDebug() << "iteration" << iteration << "in thread" << QThread::currentThreadId();
}
 
int main(int argc, char **argv)
{
    QApplication app(argc, argv);
 
    // Prepare the vector.
    QVector<int> vector;
    for (int i = 0; i < iterations; ++i)
        vector.append(i);
 
    // Create a progress dialog.
    QProgressDialog dialog;
    dialog.setLabelText(QString("Progressing using %1 thread(s)...").arg(QThread::idealThreadCount()));
 
    // Create a QFutureWatcher and conncect signals and slots.
    QFutureWatcher<void> futureWatcher;
    QObject::connect(&futureWatcher, SIGNAL(finished()), &dialog, SLOT(reset()));
    QObject::connect(&dialog, SIGNAL(canceled()), &futureWatcher, SLOT(cancel()));
    QObject::connect(&futureWatcher, SIGNAL(progressRangeChanged(int, int)), &dialog, SLOT(setRange(int, int)));
    QObject::connect(&futureWatcher, SIGNAL(progressValueChanged(int)), &dialog, SLOT(setValue(int)));
 
    // Start the computation.
    futureWatcher.setFuture(QtConcurrent::map(vector, spin));
 
    // Display the dialog and start the event loop.
    dialog.exec();
 
    futureWatcher.waitForFinished();
 
    // Query the future to check if was canceled.
    qDebug() << "Canceled?" << futureWatcher.future().isCanceled();
}

QFutureWatcherクラスの説明を含んでいますので、少々、複雑になっていますが、やっていることは単純です。 QFutureWatcherクラスを使って、スレッドを起こし、QProgressDialogクラスのsetValueを20回続けてコールしています。

5行目から、spinという関数があります。この関数は、20回呼ばれます。その1回づつで、長い処理を行うデモ関数です。 この関数をコールした後、QFutureWatcherクラスのprogressValueChangedのシグナルを発生させています。
progressValueChangedのシグナルを受けて、QProgressDialogのsetValueでプログレスバーの表示が切り替わる仕組みです。

実行すると以下のような画面が表示され、プログレスバーが100%に達すると自動で終了します。


Qtでプログレスバーをmarquee表示へ切り替えるのは、簡単です。
上記のmain.cppの32行を以下のように変更するだけです。
[main.cpp]
1
2
//    QObject::connect(&futureWatcher, SIGNAL(progressRangeChanged(int, int)), &dialog, SLOT(setRange(int, int)));
    dialog.setRange(0, 0);

では、これを実行してみましょう。


簡単ですね。プログレスの範囲を0固定にしてしまうとmarquee表示へ切り替わります。

このmarquee表示は、Windows2000でも同じように表示できます。(95系はわかりません。)
また、ドキュメントには、それらしい表記がありませんので、ひょっとすると、正式な対応でないかもしれませんので、ご了解の上、ご利用ください。
(少なくとも、4.5.1,4.5.2での動作は、同じでした。)

わかってしまえば、そうかと思うのですが、 筆者は、このやり方にたどり着くまでに、大変、長い時間を要しました。
少しでも、この記事が、皆さんの手助けになれば幸いです。

もっと、Qt関連について詳しく知りたい方は、以下の本なども良いと思います。
Qtに関する日本語の本が少ないですね。「入門書」は、さすがに、このページを読まれるくらいの方は不要だと思います。
やっぱり、本+ネット+試してみる!!の3本柱でやっていく以外にないように思います。


コメント

コメントをどうぞ







  • はてなブックマークへ追加する
  • Facebookでシェアする
  • twitter でつぶやく
  • Google Plusでシェアする
  • Pocketでシェアする
ページトップへ