内部QEventLoopで関数を呼び出すQTimerを使用しているときに、最近これに遭遇しました
QTimer インスタンスがあるとします。
QTimer* timer = new QTimer;
コンストラクターのどこかでそれを開始すると、100msごとに1回刻み始めます
timer->start(100);
楽しい部分です。内部 QEventLoop を持つスロットに接続します。
void SlotFunction()
{
qDebug() << "entered";
QEventLoop loop;
loop.exec();
}
このループがいかに馬鹿げているかはさておき、スロットの処理を終了することはなく、タイマーの後続のタイムアウトが実行キューにスタックし続けることがわかります。すべてが順調で、あるべき姿です。
本来あるべきでないことは次のとおりです。QEventLoop は、スロットが無意識にアイドル状態になっている間もアプリの応答性を維持するため、次のようなボタンとその clicked() スロットを作成できます。
void OnClicked()
{
timer->start(100);
}
ここで行っていることは、基本的に現在のタイマー サイクルを再起動することであり、それ以下でもそれ以上でもありません。右?いいえ!この再起動後、SlotFunction は再び起動し、タイマーの再起動後のティックが実際にはそれ以前に発行された他のすべてのティックと等しくないことを示唆しています...
私の唯一の質問は: WTF ?! タイマーを手動で再起動すると、スロットの追加時間を入力できるようになるのはなぜですか? freenodeで聞いてみたのですが、「あるべき姿です」という返事しか返ってきませんでした。