1. ホーム
  2. c++

[解決済み] QTimer::singleShot(0, object SLOT(obj_slot())) は何をするのですか?

2022-02-16 15:49:30

質問

私はQtを学んでいる初心者です。 をダウンロードすることができます。で ダウンロードマネージャ.cpp であり、メンバ関数は以下の通りである。

void DownloadManager::append(const QUrl &url)
{
    if (downloadQueue.isEmpty())
        QTimer::singleShot(0, this, SLOT(startNextDownload()));

    downloadQueue.enqueue(url);
    ++totalCount;
}

  • 私は、なぜ downloadQueue が空だと startNextDownload() を追加する前に、urlを追加します。 (注意してください。 startNextDownload() はプログラムを終了させます。 downloadQueue が空である場合)
  • 理由がよくわからない。 QTimer::signleShot(x, y, z) が全く使用されていません。私の理解では、0ミリ秒の遅延でスロットを作動させるタイマーです。
  • Qt Assistant を見ても、singleShot が、与えられたミリ秒間隔で繰り返しスロットを起動するための1回限りの設定なのか、それとも1回限りの設定なのかが分かりませんでした。

明確にしてください。

初心者で、こんな例では。

statement1;
statement2;

よく見かける statement1 の作業に移る前に実行し、終了しています。 statement2 . しかし、Qtを学ぼうとして、与えられた例を読むと、私は SLOT(startNextDownload()) の後に活性化されます。 downloadQueue.enqueue(url); が行われました。私が理解しようとしているのは なぜ はこのように動作します。

解決方法は?

現在の質問のタイトルに対する回答

を呼び出すたびに QTimer::singleShot(...) が実行されるのは イベントループが呼び出されたスレッドの **. メインスレッドから起動された場合、イベントループは app.exec() .

Qt-Network-Manager-Exampleによると、この関数は、以下のように呼ばれています。 そのため、シングルショットはキューが完全に満たされた後に処理されます。qt のドキュメントではこのトピックについてまだそれほど明確になっていないので、イベント処理などの詳細については以下を参照してください。 こちら .


旧質問のタイトルに対する回答

先に言っておくと、タイマーはダウンロードを別スレッドで行うためのものです。そのため、GUIはレスポンスよく動作します。

完全な downloadNext() メソッドは再帰的です。これは一度だけ呼ばれ、キューが空になるまで呼び出されます。 これを見てください。

void DownloadManager::append(const QStringList &urlList)
{
    foreach (QString url, urlList)
        append(QUrl::fromEncoded(url.toLocal8Bit())); //Call for only one URL
  ...
}

void DownloadManager::append(const QUrl &url)
{
    if (downloadQueue.isEmpty())
        //I'm only called if the queue is empty! And I will be called after the next line. Not instantly!
        QTimer::singleShot(0, this, SLOT(startNextDownload()));  

    downloadQueue.enqueue(url);
    ++totalCount;
}

キューが空になった後、各メソッドは戻り、少なくともダウンロードが完了した旨のメッセージが出力されます。

では、なぜこれがうまくいくのでしょうか? 下記の第1章をご覧ください。