На этом шаге рассмотрим класс QTimer.
Использование объекта класса QTimer гораздо проще, чем использование события таймера, определенного в классе QObject. К недостаткам работы с событием таймера относится необходимость наследования одного из классов, наследующих класс QObject. Затем в унаследованном классе нужно реализовать метод, принимающий объекты события таймера. А если в объекте создается более одного таймера, то возникает необходимость различать таймеры, чтобы узнать, который из них явился инициатором события.
Для ликвидации этих неудобств Qt предоставляет класс таймера QTimer, являющийся непосредственным наследником класса QObject. Чтобы запустить таймер, нужно создать объект класса QTimer, а затем вызвать метод start(). В параметре метода передается значение интервала запуска в миллисекундах.
Класс QTimer также содержит статический метод singleShot() для одноразового режима отработки таймера (режима singleshot). С его помощью можно запустить одноразовый таймер без создания объекта класса QTimer. Первый параметр метода задает интервал запуска, а второй является указателем на объект, с которым должно осуществляться соединение. Слот для соединения передается в третьем параметре. Этим можно воспользоваться, например, для прекращения работы демоверсии программы через 10 секунд после ее запуска.
QTimer::singleShot(10 * 1000, &app, SLOT(quit()));
Файлы приложения можно взять здесь.
По истечении интервала запуска таймера отправляется сигнал timeout(), который нужно соединить со слотом, выполняющим нужные действия.
При помощи метода setInterval() можно изменить интервал запуска таймера. Если таймер был активен, то он будет остановлен и запущен с новым интервалом, и ему будет присвоен новый идентификационный номер.
При помощи метода isActive() можно проверить, находится таймер в активном состоянии.
Вызовом метода stop() можно остановить таймер.
Бывают случаи, когда нужно заблокировать выполнение основного потока программы на какое-то время, для того чтобы, например, дождаться доступности ресурса предоставляемого другой программой или сервером, без которого программа не может продолжать свою работу дальше. Реализуем функцию delay(), которая будет принимать одно значение целого типа, означающее время продолжительности блокировки в миллисекундах. Пример приложения, использующего блокировку, приведен на рисунке 1.
Рис.1. Пример использования блокировки
void delay(int n) { //Создаем блокирующую функцию при помощи объекта класса цикла событий //QEventLoop, сам объект создан локально и он автоматически будет //разрушен в конце блокировки QEventLoop loop; //Соединение, выполненное в методе singleShot(), прервет блокировку //по истечении времени n, вызовом слота quit() из объекта цикла событий (loop) QTimer::singleShot(n, &loop, SLOT(quit())); //Вызов метода exec() блокирует выполнение программы loop.exec(); }
Файлы приложения можно взять здесь.
Программа, окно которой изображено на рис. 2, реализует часы, отображающие дату и время. Отображаемая информация актуализируется в соответствии с установленным полусекундным интервалом запуска таймера.
Рис.2. Электронные часы
Рассмотрим заголовочный файл приложения, представленного на рисунке 2:
class Clock : public QLabel { Q_OBJECT public: Clock(QWidget* pwgt = 0) : QLabel(pwgt) { //создается объект таймера (указатель ptimer) QTimer* ptimer = new QTimer(this); //его сигнал timeout() соединяется со слотом slotUpdateDateTime(), //ответственным за обновление отображаемой информации connect(ptimer, SIGNAL(timeout()), SLOT(slotUpdateDateTime())); //вызов метода start() запускает таймер, в него передается интервал запуска ptimer->start(500); slotUpdateDateTime(); } public slots: //Слот slotUpdateDateTime() получает актуальную дату и время //с помощью метода currentDateTime(). Затем он, используя параметр локализации //Qt::SystemLocaleDate, преобразует дату и время к строковому типу и передает //в метод setText() для отображения void slotUpdateDateTime() { QString str = QDateTime::currentDateTime().toString(Qt::SystemLocaleDate); setText("<H2><CENTER>" + str + "</CENTER></H2>"); } };
Файлы приложения можно взять здесь.
В качестве еще одной альтернативы в Qt предусмотрено минималистское решение для таймера — это класс QBasicTimer, предоставляющий только четыре метода: isActive(), start(), stop() и timerId(), которые по своей функциональности аналогичны методам класса QTimer. Исключение составляет только метод start(). Помимо первого параметра, задающего интервал, в этот метод вторым параметром передается указатель на объект QObject, который будет получать события таймера. Таким образом, вам нужно будет реализовать в классе, унаследованном от класса QObject, метод обработки события таймера QObject::timerEvent().
На следующем шаге рассмотрим работу с датой и временем.