2015-06-25 2 views
2

Что произойдет, если я запускаю запуск QTimer через равные промежутки времени, но слот, реагирующий на сигнал таймаута, блокирует основной цикл дольше, чем другой интервал таймера. Будут ли временные сигналы затем укладываться в основной цикл событий Qt и обрабатываться один за другим, как только цикл событий будет запущен снова?Обработка тайм-аута QTimer, когда основная очередь событий Qt заблокирована

Если да, что произойдет, если несколько событий таймаута уложены в очередь событий, но таймер деактивирован до того, как их можно обработать?

ответ

2

Если объект QTimer и приемник сигналов относятся к одному потоку, очереди не происходит. timeout() сигнал не будет (и не может) отправляться снова, пока поток управления не перейдет в цикл событий, и это произойдет не до тех пор, пока слот не будет полностью выполнен (если в слот не вызывается QApplication::processEvents, что может превратить это в беспорядок). Но если ваш слот выполнялся дольше, чем интервал таймера, timeout() будет отправлен после того, как цикл событий будет бесплатным, поэтому ваш слот будет снова вызван снова. Но QTimer не отправит два сигнала timeout() ближе своего интервала.

Если QTimer находится в другом потоке, и эта нить не занята чем-то другим, она будет регулярно отправлять сигналы timeout() независимо от того, насколько хорошо слот в другом потоке. Именно здесь поступает система сигнальных слотов Qt, и она будет выставлять в очередь выданные сигналы. Если ваш слот медленный, он будет вызывать его несколько раз без задержки. Если вы остановите таймер, он не отменит уже отправленные сигналы, и слот может быть вызван несколько раз после него. Кроме того, если вы остановите таймер, всегда есть возможность отправить другой сигнал в этот момент, и ваш слот будет вызван еще раз.

Если вам нужны строгие интервалы между вызовами слота независимо от времени выполнения слота, вы должны использовать таймеры с одним выстрелом. В конце вашего слота запустите таймер с одним выстрелом. По истечении этого времени он будет вызывать ваш слот и деактивировать, поэтому вы можете запустить его снова в конце слота.

Если логика вашей программы зависит от состояния таймера, вы должны проверить, что таймер активен в начале вашего слота. Не гарантируется, что таймер будет активен при выполнении слота.

Смежные вопросы