Таймер в Qt
Оглавление
В программах часто возникает потребность в периодическом повторении определенных действий через заданные промежутки времени. Конечно, в некоторых случаях, для задания временного интервала вызова функции, можно воспользоваться и объектом класса QTime и сделать примерно следующее:
QTime time;
time.start();
for(;time.elapsed() < 1000;) {
}
function();
Но такой подход обладает огромным недостатком. Исполнение цикла на секунду приостанавливает выполнение всей программы. Вследствие этого, события интерфейса пользователя не будут обрабатываться, и если одно из окон перекроет окно приложения, то оно все это время перерисовываться не будет, то есть приложение на все это время "замрет".
В подобных ситуациях можно, вызовом метода processEvents() класса приложения QAppiication, приостанавливать исполнение цикла, для того, чтобы программа получала возможность обработки поступивших событий.
Например:
QTime timer;
timer.start () ;
for(;timer.elapsed() < 1000;)
{
qApp->processEvents(0);
}
Данный подход обладает другим недостатком — он не асинхронен. То есть, наша программа будет в состоянии обрабатывать поступающие события, но не в состоянии исполняться дальше, пока цикл не завершится до конца.
Таймер представляет собой решение этой проблемы. События таймера происходят асинхронно и не прерывают обработку других событий, выполняемых в том же потоке. Таймер — это гарант, обеспечивающий передачу управления программе. Долгая обработка событий влечет за собой задержки выполнения события таймера, то есть таймер ждет своего времени, как и остальные события. Период между событиями таймера носит название интервал запуска (firing interval). Таймер переходит в сигнальное состояние по истечении интервала запуска, который указывается в миллисекундах. Точность интервала запуска ограничивается, к сожалению, точностью системных часов, а это значит, что на таймер нельзя полагаться как на секундомер. ОС Windows 98 отличается самой плохой точностью — она составляет 55 миллисекунд, во всех же остальных ОС, поддерживаемых Qt, точность лежит в пределах одной миллисекунды. Следовательно, при написании программы имитации часов будет нелишним, после каждого сообщения таймера, проверять текущее время. Так как временной интервал, задаваемый в таймере, представляет собой целое число, то самый большой временной интервал, который можно установить — 24 дня. Эту проблему можно решить введением дополнительного счетчика для таймера.
Существует много областей для применения таймера. Например, в текстовом редакторе его используют для автоматического сохранения файлов или в качестве альтернативы многопоточности, разбив программу на части, каждая из которых будет выполняться при наступлении события таймера. Также таймер используется для отображения информации о состоянии данных, изменяющихся с течением времени. Таймер незаменим для избежания разногласий, связанных с мощностью и возможностями разных компьютеров, то есть для исполнения программ в режиме реального времени.
События таймера можно использовать и в мультипоточном программировании, для каждого потока, имеющего цикл сообщений (event loop). Для запуска цикла сообщений в потоке нужно вызвать метод QThread::exec().
Читать далее: Событие таймера